This query worked perfectly until the moment I went in for vacations, now itdoes not run anymore and does not merge, dont know what it can be
MERGE INTO STG_FATO_MACRO_GESTAO AS FAT
USING(SELECT DISTINCT
COD_EMPRESA
,FUN.MATRICULA AS FUN_MAT
,APR.MATRICULA AS APR_MAT
,FUN.CPF AS FUN_CPF
,APR.CPF AS APR_CPF
,APR.DAT_DESLIGAMENTO
,YEAR(APR.DAT_DESLIGAMENTO)*100+MONTH(APR.DAT_DESLIGAMENTO) AS DESL
,FUN.DATA_ADMISSAO
,YEAR(FUN.DATA_ADMISSAO)*100+MONTH(FUN.DATA_ADMISSAO) AS ADM
, CASE WHEN YEAR(APR.DAT_DESLIGAMENTO)*100+MONTH(APR.DAT_DESLIGAMENTO) <= YEAR(FUN.DATA_ADMISSAO)*100+MONTH(FUN.DATA_ADMISSAO) THEN 1 ELSE 0 END AS ADMITIDO
,CASE WHEN FUN.DATA_ADMISSAO <= (APR.DAT_DESLIGAMENTO + INTERVAL '90' DAY) THEN 1 ELSE 0 END AS APR_90
FROM (SELECT CPF,DATA_ADMISSAO, MATRICULA, COD_EMPRESA FROM DIM_FUNCIONARIO
WHERE PROFISSAO NOT LIKE '%APRENDIZ%') AS FUN
INNER JOIN (SELECT DISTINCT
CPF,DAT_DESLIGAMENTO,MATRICULA
FROM HST_APRENDIZ
WHERE FLAG_FECHAMENTO = 2
AND DAT_DESLIGAMENTO IS NOT NULL) AS APR
ON FUN.CPF = APR.CPF) AS APR_90
ON FAT.COD_EMPRESA = APR_90.COD_EMPRESA
AND FAT.MATRICULA = APR_90.FUN_MAT
AND APR_90.APR_90 = 1
AND APR_90.ADMITIDO = 1
WHEN MATCHED THEN
UPDATE SET APRENDIZ_EFETIVADO_90 = 1
;
when running this query returns me this error:
"The search condition must fully specify the Target table primary index and partition column(s) and expression must match INSERT specification primary index and partition column(s). "
I have a table like this
CREATE TABLE "modules" ( `ID` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `version` TEXT, `deployID` INTEGER )
I want to be able to get all the rows from this database where the version is different between different deploy ID's. So, say I have a deploy ID 2 and a deployID 3 - my table might have 2000 odd modules for each of these deploys. I want to only get the rows where the name is the same but the version is different. Is this possible? I thought this query would do it but it seems to be returning me everything - twice!
SELECT a.* FROM modules a
INNER JOIN modules b
ON a.name == b.name
WHERE a.version != b.version
AND a.deployID = 3
AND b.deployID = 2
If you only care about deployids 2 and 3:
select m.*
from modules m
where
m.deployid in (2, 3)
and
exists (
select 1 from modules
where
name = m.name
and
deployID <> m.deployID
and
version <> m.version
)
If you don't need this condition:
deployID <> m.deployID
you can remove it.
I would probably use an exists query here:
SELECT m1.*
FROM modules m1
WHERE EXISTS (SELECT 1 FROM modules m2
WHERE m1.name = m2.name AND
m1.deployID <> m2.deployID AND m1.version <> m2.version);
Or maybe you want a more specific version:
SELECT m1.*
FROM modules m1
WHERE EXISTS (SELECT 1 FROM modules m2
WHERE m1.name = m2.name AND
LEAST(m1.deployID, m2.deployID) = 2 AND
GREATEST(m1.deployID, m2.deployID) = 3);
Guys I have such a problem.
I know how to write a good select statement but I have no idea how to turn it into a corresponding update.
Im still learning plsql
Here is my select
select * --count(*)
from POLISY_OT ot
join polisy p on p.poli_id = ot.ot_poli_id
join sou.rai_skl rs on rs.ot_id = ot.ot_id
where ot_under_promil = 0
and ot_skladka_rok <> ot_skladka_netto_rok
and ot_rodzaj_um = 'OP'
and ot_rodzaj = 'D'
and ot_produkt_id = 17
and p.poli_status in ('AK', 'CZ')
and rs.skl_roczna = ot.ot_skladka_rok;
now I would like to wrap it up with an update and create something like this
update (
select * --count(*)
from POLISY_OT ot
join polisy p on p.poli_id = ot.ot_poli_id
join sou.rai_skl rs on rs.ot_id = ot.ot_id
where ot_under_promil = 0
and ot_skladka_rok <> ot_skladka_netto_rok
and ot_rodzaj_um = 'OP'
and ot_rodzaj = 'D'
and ot_produkt_id = 17
and p.poli_status in ('AK', 'CZ')
and rs.skl_roczna = ot.ot_skladka_rok)
set ot_skladka_rok = ot_skladka_netto_rok;
First, I really hope you aren't a student asking for homework help. That really bugs me.
On the assumption it's not, it's a little hard to tell exactly which columns belong to which tables, given that you didn't include the table aliases throughout.
I read this as that you wanted to update a column based on the value in another table, restricting the table updates to records that match a third table).
So I think you want something like this:
UPDATE polisy_ot ot
SET ot_skladka_rok =
(SELECT ot_skladka_netto_rok
FROM sou.rai_skl rs
WHERE rs.ot_id = ot.ot_id
AND rs.skl_roczna = ot.ot_skladka_rok)
WHERE ot_under_promil = 0
AND ot_skladka_rok <> ot_skladka_netto_rok
AND ot_rodzaj_um = 'OP'
AND ot_rodzaj = 'D'
AND ot_produkt_id = 17
AND EXISTS (SELECT NULL
FROM polisy p
WHERE p.poli_id = ot.ot_poli_id
AND p.poli_status IN ('AK', 'CZ'))
Good luck,
Stew
I need to manage hierarchy data storing in my database. But I have a problem now. Please see my example
I have a table called COMMON.TASK_REL
My second table is called Common. task
I suppose need to sort the task_seq and return a result like below:
Task Name || Task_Seq
Item1 1
..Item1.2 1
...Item1.2.1 1
..Item1.1 2
Here is my query
--Common task SQL modify --
WITH ctLevel
AS
(
SELECT
C_TASK_ID AS Child
,P_Task_ID AS Parent
,common_task.TASK_SEQ AS taskOrder
,1 AS [Level]
,CAST(C_TASK_ID AS VARCHAR(MAX)) AS [Order]
,CAST (Replicate('.', 1) + common_task.TASK_NAME AS VARCHAR(25)) AS [Task_Name]
FROM
[COMMON.TASK_REL] as common_task_rel,
[COMMON.TASK] as common_task
WHERE common_task_rel.C_TASK_ID = common_task.TASK_ID
and common_task.[TASK_TYPE] = 'B' AND common_task.[MODULE_CODE] = 'LWRPT'
AND common_task.[STATUS] <> 'D'
UNION ALL
SELECT
C_TASK_ID AS Child
,P_Task_ID AS Parent
,common_task.TASK_SEQ AS taskOrder
,[Level] + 1 AS [Level]
,[Order] + '.' + CAST(C_TASK_ID AS VARCHAR(MAX)) AS [Order]
,CAST (Replicate('.', [Level] + 1) + common_task.TASK_NAME AS VARCHAR(25)) AS [Task_Name]
FROM [COMMON.TASK_REL] as common_task_rel
INNER JOIN ctLevel
ON ( P_Task_ID = Child ) , [COMMON.TASK] as common_task
WHERE common_task_rel.C_TASK_ID = common_task.TASK_ID
and common_task.[TASK_TYPE] = 'B' AND common_task.[MODULE_CODE] = 'LWRPT'
AND common_task.[STATUS] <> 'D'
)
-- Viewing Data
SELECT Child ,Parent ,taskOrder,Level,[Order],Task_Name
FROM ctLevel
GROUP BY Child ,Parent ,taskOrder,Level,[Order],Task_Name
order by [Order];
GO
But my result returns duplicated rows:
Anyone can help me correct my query? Thanks
I believe that your duplicates are coming from your root/anchor query. You should add the following to that query:
AND Task_Seq = 0
Basically, you only want the root to be set up as the beginning of the tree. 301|300 should not be picked up until the recursion section (the part after union all)
If that does not make sense, then I can repaste your query with the modification, but that seemed unnecessary for a small change.
I have an column in table where this column name is items it contains value like this
itemID items
1 school,college
2 place, country
3 college,cricket
4 School,us,college
5 cricket,country,place
6 football,tennis,place
7 names,tennis,cricket
8 sports,tennis
Now I need to write a search query
Ex: if the user types 'cricket' into a textbox and clicks the button I need to check in the column items for cricket.
In the table I have 3 rows with cricket in the items column (ItemId = 3, 5, 7)
If the user types in tennis,cricket then I need to get the records that match either one. So I need to get 5 row (ItemId = 3, 5, 6, 7, 8)
How do I write a query for this requirement?
You need to start by redesigning your database as this is is a very bad structure. You NEVER store a comma delimited list in a field. First think about waht fields you need and then design a proper database.
The very bad structure of this table (holding multiple values in one column) is the reason you are facing this issue. Your best option is to normalize the table.
But if you can't, then you can use the "Like" operator, with a wildcard
Select * From Table
Where items Like '%cricket%'
or
Select * From Table
Where items Like '%cricket%'
or items Like '%tenis%'
You will need to dynamically construct these sql queries from the inputs the user makes. The other alternative is to write code on the server to turn the comma delimited list of parameters into a table variable or temp table and then join to it..
Delimited values in columns is almost always a bad table design. Fix your table structure.
If for some reason you are unable to do that, the best you can hope for is this:
SELECT * FROM [MyTable] WHERE items LIKE '%CRICKET%'
This is still very bad, for two important reasons:
Correctness. It would return values that only contain the word cricket. Using your tennis example, what if you also had a "tennis shoes" item?
Performance. It's not sargable, which means the query won't work with any indexes you may have on that column. That means your query will probably be incredibly slow.
If you need help fixing this structure, the solution is to add another table — we'll call it TableItems — with a column for your ItemID that will be a foreign key to your original table and an item field (singular) for each of your item values. Then you can join to that table and match a column value exactly. If these items work more like categories, where you want to rows with the "Cricket" item to match the same cricket item, you also want a third table to be an intersection between your original table and the other one I just had you create.
For a single item:
SELECT itemID, items FROM MyTable WHERE items LIKE '%cricket%'
For multiple items:
SELECT itemID, items FROM MyTable WHERE items LIKE '%tennis%' or items LIKE '%cricket%'
You'll need to parse the input and split them up and add each item to the query:
items LIKE '%item1%' or items LIKE '%item2%' or items LIKE '%item3%' ...
I think that in the interest of validity of data, it should be normalized so that you split the Items into a separate table with an item on each row.
In either case, here is a working sample that uses a user defined function to split the incoming string into a Table Variable and then uses JOIN with a LIKE
CREATE FUNCTION dbo.udf_ItemParse
(
#Input VARCHAR(8000),
#Delimeter char(1)='|'
)
RETURNS #ItemList TABLE
(
Item VARCHAR(50) ,
Pos int
)
AS
BEGIN
DECLARE #Item varchar(50)
DECLARE #StartPos int, #Length int
DECLARE #Pos int
SET #Pos = 0
WHILE LEN(#Input) > 0
BEGIN
SET #StartPos = CHARINDEX(#Delimeter, #Input)
IF #StartPos < 0 SET #StartPos = 0
SET #Length = LEN(#Input) - #StartPos - 1
IF #Length < 0 SET #Length = 0
IF #StartPos > 0
BEGIN
SET #Pos = #Pos + 1
SET #Item = SUBSTRING(#Input, 1, #StartPos - 1)
SET #Input = SUBSTRING(#Input, #StartPos + 1, LEN(#Input) - #StartPos)
END
ELSE
BEGIN
SET #Pos = #Pos+1
SET #Item = #Input
SET #Input = ''
END
INSERT #ItemList (Item, Pos) VALUES(#Item, #Pos)
END
RETURN
END
GO
DECLARE #Itemstable TABLE
(
ItemId INT,
Items VarChar (1000)
)
INSERT INTO #Itemstable
SELECT 1 itemID, 'school,college' items UNION
SELECT 2, 'place, country' UNION
SELECT 3, 'college,cricket' UNION
SELECT 4, 'School,us,college' UNION
SELECT 5, 'cricket,country,place' UNION
SELECT 6, 'footbal,tenis,place' UNION
SELECT 7, 'names,tenis,cricket' UNION
SELECT 8, 'sports,tenis'
DECLARE #SearchParameter VarChar (100)
SET #SearchParameter = 'cricket'
SELECT DISTINCT ItemsTable.*
FROM #Itemstable ItemsTable
INNER JOIN udf_ItemParse (#SearchParameter, ',') udf
ON ItemsTable.Items LIKE '%' + udf.Item + '%'
SET #SearchParameter = 'cricket,tenis'
SELECT DISTINCT ItemsTable.*
FROM #Itemstable ItemsTable
INNER JOIN udf_ItemParse (#SearchParameter, ',') udf
ON ItemsTable.Items LIKE '%' + udf.Item + '%'
Why exactly are you using a database in the first place?
I mean : you are clearly not using it's potential. If you like using comma separated stuff, try a file.
In MySQL, create a fulltext index on your table:
CREATE FULLTEXT INDEX fx_mytable_items ON mytable (items)
and issue this query:
SELECT *
FROM mytable
WHERE MATCH(items) AGAINST ('cricket tennis' IN BOOLEAN MODE)