Just demo. I have two table
Table a (id, name)
--id---name----
1 John
2 Jack
3 Maria
4 Bill
Table b (id, empid, datewrk)
--id---empid----datewrk----
1 1 2012-12-12
2 2 2012-12-14
3 3 2012-12-16
4 4 2012-12-17
I want update all name = null in table a where date in table b <= '2012-12-14', the result is
--id---name--
1 NULL
2 NULL
I have try code bellow but no work (only work with SELECT statement). I try in MySql Workbench and SQL Server 2012
UPDATE a
SET name = NUll
WHERE id IN (SELECT a.id FROM a
JOIN b ON a.id = b.empid
WHERE b.datewrk <= '2012-12-14');
Thank.
For mysql
UPDATE a
JOIN b ON a.id = b.empid
SET a.name = NUll
WHERE b.datewrk <= '2012-12-14';
You don't need a subquery just join your table put set clause in right place then where clause
Fiddle Demo
Your Update Statement should work, but in order to compare you have to convert '2012-12-14' to date.
UPDATE a
SET name = NULL
WHERE id IN (
SELECT empid FROM b
WHERE datewrk <= STR_TO_DATE('2012-12-14', '%Y-%m-%d'));
Note that in your subquery you don't need table A.
Hope this helps.
Related
i am new to sql and need help with a query. I have two tables user and user_family which contains data like
USER
ID
Date-Of-birth
User_Id
1
2021-05-21
28371
2
2021-04-17
28372
USER_FAMILY
ID
family_detail_id
User_Id
1
1
28371
2
1
28374
3
1
28375
4
2
28372
5
2
28373
6
2
28378
7
2
28379
i want to run a query which checks if current date in equal to someones dob in my user table, if yes i want to return all entries from user_family table which has same family_detail_id to someone whose dob has been matched.
Suppose if the current date is 2021-05-21 then the result should be,
ID
family_detail_id
User_Id
dob
birthday_user_id
2
1
28374
2021-05-21
28371
3
1
28375
2021-05-21
28371
You can use a self-join on the family_detail_id,
select f2.*
from user u join user_family f on f.id=u.id
join user_family f2 on f2.family_detail_id=f.family_detail_id
where u.Date_Of_birth=currdate();
Working Fiddle
I would suggest exists. Assuming that user.id matches to user_family.family_detail_id, then this looks like:
select uf.*
from user_family uf
where exists (select 1
from user u
where u.family_detail_id = u.id and
u.dob = curdate()
);
You may try below query, assuming USER_ID is the linking column between the two tables -
select uf1.*
from user_family uf1
where uf1.family_detail_id in
(select uf.family_detail_id
from user_family uf
inner join user u on u.user_id = uf.user_id
where u.Date-Of-birth = CURDATE()); --DATE(u.Date-Of-birth) = CURDATE()
HTH!
situation:
table 1 - #__virtuemart_products
virtuemart_product_id | product_special
PRODUCTS_IDS | 0 or 1
table 2 - #__virtuemart_product_badges
virtuemart_product_id | product_badge
PRODUCTS_IDS | for this situation code 3
I have a default SQL
SELECT p.`virtuemart_product_id`
FROM `#__virtuemart_products` as p
WHERE p.`product_special` = 1;
results is product IDs like 2,3,225,...
I need modify this SQL syntax for select IDs from 2 different tables and return one column.
If I modify syntax like that:
SELECT p.`virtuemart_product_id`, badges_table.`virtuemart_product_id`
FROM `#__virtuemart_products` as p, `#__virtuemart_product_badges` as badges_table
WHERE p.`product_special` = 1 OR badges_table.`badge` = 3
Result is:
virtuemart_product_id | virtuemart_product_id
1 | 123
1 | 321
1 | 231
....
why is first column 1,1,1,...? here must be product_id, no product_special code
I need group this results into one column virtuemart_product_id
What I doing wrong?
I think what you are looking for is UNION of the IDs fetched from two different tables.
SELECT p.`virtuemart_product_id`, badges_table.`virtuemart_product_id`
FROM `#__virtuemart_products` as p, `#__virtuemart_product_badges` as
badges_table
WHERE p.`product_special` = 1 OR badges_table.`badge` = 3
What the above query is doing is, it is performing a join between the two tables with the condition that product_special should be 1 or badge should be 3. Hence, each row from one table will be joined with each row of the other table where the condition will satisfy.
To get IDs from both the tables you can get the results from each table according to condition and then perform a UNION on them. So for example
(SELECT `virtuemart_product_id` FROM `#__virtuemart_products` WHERE
`product_special` = 1)
UNION
(SELECT `virtuemart_product_id` FROM
`#__virtuemart_product_badges` WHERE `badge` = 3)
I hope this helps.
I have a table like this
itemid | propertyname | propertyvalue
___________|______________|_______________
1 | point | 12
1 | age | 10
2 | point | 15
2 | age | 11
3 | point | 9
3 | age | 10
4 | point | 13
4 | age | 11
I need a query to select all items where age greater than 10 and point less than 12.
I tried
`select itemid from table where (propertyname="point" and propertyvalue < 12)
and (propertyname="age" and propertyvalue >10)`
It gives no results. How can I make it work?
you can use an inner join
SELECT
a.itemid
FROM
yourTable a
INNER JOIN
yourTable b
ON
a.itemid=b.itemid
AND a.propertyname='point'
AND b.propertyname='age'
WHERE
a.propertyvalue<12
AND b.propertyvalue>10
ok so in table a youre lookin for all items with the name point and a value smaller 12 and in table b youre looking for all items with the name age and a value greater 10. Then you only have to look for items, which are in both tables. For this you connect the two tables over the itemid. To connect tables you use the join. Hope this will help you to understand. If not ask again :)
To join a table to itself in the same query you can include the table twice in the FROM clause, giving it a different alias each time. Then you simply proceed with building your query as if you were dealing with two separate tables that just happen to contain exactly the same data.
In the query below the table example is aliased as a and b:
SELECT a.itemid
FROM example a, example b
WHERE a.itemid = b.itemid
AND a.propertyname = 'point'
AND a.propertyvalue < 12
AND b.propertyname = 'age'
AND b.propertyname > 10
Try It:
SELECT itemid FROM test_table WHERE propertyname="point" AND propertyvalue < 12 AND itemid IN(SELECT itemid FROM test_table WHERE propertyname="age" AND propertyvalue >10)
http://sqlfiddle.com/#!9/4eafc6/1
PLs Try this
select itemid from table where (propertyname="point" and propertyvalue < 12)
or (propertyname="age" and propertyvalue >10);
Here's one idea...
SELECT item_id
, MAX(CASE WHEN propertyname = 'point' THEN propertyvalue END point
, MAX(CASE WHEN propertyname = 'age' THEN propertyvalue END age
FROM a_table
GROUP
BY item_id
HAVING age+0 > 10
AND point+0 < 12;
You can use an inner join. Meaning, it's like you're going to work with 2 tables: the first one you're going to select the name="age" and val>10, and the second one is where you're going to select name="point" and val<12.
It's like you're creating an instance of your table that doesn't really exist. It's just going to help you extract the data you need at the same time.
I request some help with MySQL when-then statement to fetch all the sid from the table after comparing multiple records having same sid but different cid-data values:
flag sid cid data
---- --- --- ----
1 300 1 john
1 300 2 john_email
1 300 3 77500
1 300 4 ok
1 301 1 jack
1 301 2 john_email
1 301 3 72210
1 301 4 notok
Here for each sid, I need to check if (sid=2 has data=john_email) AND (sid=4 has data=ok)
Only if both the conditions are satisfied, I return the sid. i.e. the output will be '300' only.
I am confused how to use the case-when-then and compare 'data' with 'john_email' and also compare data with 'ok' ... based on the cid values. Thanks for reading.
try
select sid
from your_table
group by sid
where (cid=2 and data='john_email')
or (cid=4 and data='ok')
having sum(cid=2)=1 and sum(data='john_email')=1
and sum(cid=4)=1 and sum(data='ok')=1
SQLFiddle example
You should join the table to itself, then you can check the condition in the two rows as if it was one row...
SELECT T1.sid
FROM MYTABLE T1
JOIN MYTABLE T2 ON T1.SID=T2.SID AND T1.CID=1 AND T2.CID=4
WHERE T1.DATA='john'
AND T2.DATA='ok'
Note that I used the CID values in the join clause, but you will have to adjust them if you want to join on different data rows...
What you can do is use a subquery and check if the value exists.
SELECT
*
FROM
table outertable
WHERE
( cid=2 AND data='john_email' )
AND
EXISTS ( SELECT sid FROM table WHERE cid = 4 AND data = 'ok' AND sid = outertable.sid )
I am struggling with the appropriate query to find duplicates while at the same time respecting the effective start and end dates for the record. Example data below.
ClientName ClientID EffectiveStart EffectiveEnd
A 1 1900-01-01 2100-01-01
A 1 1900-01-01 2100-01-01
B 2 1900-01-01 2012-05-01
C 2 2012-05-01 2100-01-01
D 3 1900-01-01 2012-05-01
E 3 2012-04-30 2100-01-01
F 4 2012-04-15 2100-01-01
The output I am looking for is below.
ClientName ClientID
A 1
D 3
E 3
The logic is that Client A has ID 1 duplicated. Client B and C have a duplicate (2) BUT the date ranges are such that the two duplicates DO NOT overlap each other, which means they should not be considered duplicates. Client D and E have ID 3 duplicated AND the date ranges overlap so it should be considered a duplicate. Client F does not have a duplicate so should not show in the output.
Any thoughts? Questions?
There are two versions. Exists is simpler but likely slower than join. Exists checks for each record if there is an overlapping record per same clientid; it is bound to find at least one, itself, hence group by and having.
select distinct ClientName, ClientID
from Table1
where exists
(
select null
from table1 test1
where test1.clientid = table1.clientid
and test1.EffectiveStart < table1.EffectiveEnd
and test1.EffectiveEnd > table1.EffectiveStart
group by test1.ClientID
having count (*) > 1
)
Join does the same, but as grouping is done on all records its having has to count them all.
select test1.clientid
from table1 test1
join table1 test2 on test1.clientid = test2.clientid
where test1.EffectiveStart < test2.EffectiveEnd
and test1.EffectiveEnd > test2.EffectiveStart
group by test1.clientid
having count (*) > (select count (*)
from table1
where clientid = test1.clientid)
I omitted retrieval of clientname because people hate to see nested queries.
Live test is at Sql Fiddle.
Will need a PK
select c1.name, c2.name, c1.id
from client c1
join client c2 on c1.id = c2.id and c1.PK < c2.PK
where c1.Start > c2.End or c1.End < c2.Start
Determine Whether Two Date Ranges Overlap please give him a +1