I have table:
+----+-------+-------------+
| id | code | value_check |
| 1 | p-01 | OK |
| 2 | p-01 | NOT OK |
| 3 | p-01 | OK |
| 4 | p-02 | OK |
| 5 | p-02 | OK |
| 6 | p-02 | OK |
+----+-------+-------------+
How can I select record which having 'OK' group by code,but if there is one or more 'NOT OK' on value_check then don't need to select
expected result:
code
p-02
i have tried my query can get the result but its very slow
this is my query :
SELECT code FROM table
WHERE code
NOT IN (SELECT code FROM table
WHERE value_check = 'NOT OK' GROUP BY code)
GROUP BY code
any other solution?
Check whether the total count is equal to the count of rows having value as OK using HAVING clause.
Query
select `code` from `your_table_name`
group by `code`
having count(*) = sum(`value_check` = 'OK');
Find a demo here
Try below with conditional aggregation
select code from table
group by code
having sum(case when value_check='NOT OK' then 1 else 0 end)=0
You can try it also with correlated subquery:
demo
SELECT distinct code FROM cte1 a
WHERE NOT exists (SELECT 1 FROM cte1 b where a.code=b.code and val = 'NOT OK')
SELECT DISTINCT x.code
FROM my_table x
LEFT
JOIN my_table y
ON y.code = x.code
AND y.value_check = 'not ok'
WHERE x.value_check = 'ok'
AND y.id IS NULL
Related
I have a mysql table with 2 columns.
+---------+-----------+
| Barcode | StationID |
+---------+-----------+
| 89411 | 1 |
| 89411 | 2 |
| 89411 | 3 |
| 89412 | 1 |
| 89413 | 1 |
+---------+-----------+
I would like to select all valus from Barcode column which have StationID = 1 and do NOT have a StationID different than 1.
As shown in the picture Barcode 89411 appears three times with different StationID and should be excluded from the result.
Can you help me make a query?
Another approach is to use an EXISTS query:
SELECT t1.*
FROM yourTable t1
WHERE
t1.StationID = 1 AND
NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE t1.Barcode = t2.Barcode AND t2.StationID <> 1);
Demo
Use aggregation function GROUP_CONCAT, and use HAVING clause to filter out those barcodes, which has only one StationID, that is '1':
SELECT barcode, GROUP_CONCAT(DISTINCT StationID) AS stations
FROM table_name
GROUP BY barcode
HAVING stations = '1';
Try this: https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=641d334c5f9e57bbdde07e4f24365f88
select barcode from tablename
group by barcode
having sum(case when sanctionid=1 then 0 else 1 end)=0
output:
barcode
89412
89413
I'm currently in the process of converting data from one structure to another, and in the process I have to take a status id from the first entry in the group and apply it to the last entry in that same group. I am able to target and update the last item in the group just fine when using a hard-coded value, but I'm hitting a wall when trying to use the status_id from the first entry. Here is an example of the data structure.
-----------------------------------------------------------
| id | ticket_id | status_id | new_status_id | created_at |
-----------------------------------------------------------
| 1 | 10 | NULL | 3 | 2018-06-20 |
| 2 | 10 | 1 | 1 | 2018-06-22 |
| 3 | 10 | 1 | 1 | 2018-06-23 |
| 4 | 10 | 1 | 1 | 2018-06-26 |
-----------------------------------------------------------
So the idea would be to take the new_status_id of ID 1 and apply it to the same field for ID 4.
Here is the query that works when using a hard-coded value
UPDATE Communications_History as ch
JOIN
(
SELECT communication_id, MAX(created_at) max_time, new_status_id
FROM Communications_History
GROUP BY communication_id
) ch2
ON ch.communication_id = ch2.communication_id AND ch.created_at = ch2.max_time
SET ch.new_status_id = 3
But when I use the following query, I get Unknown column ch.communication_id in where clause
UPDATE Communications_History as ch
JOIN
(
SELECT communication_id, MAX(created_at) max_time, new_status_id
FROM Communications_History
GROUP BY communication_id
) ch2
ON ch.communication_id = ch2.communication_id AND ch.created_at = ch2.max_time
SET ch.new_status_id = (
SELECT nsi FROM
(
SELECT new_status_id FROM Communications_History WHERE communication_id = ch.communication_id AND status_id IS NULL
) as ch3
)
Thanks!
So I just figured it out using variables. It turns out the original "solution" only worked when there was one ticket's worth of history in the table, but when all the data was imported, it no longer worked. However, this tweak did seem to fix the issue.
UPDATE Communications_History as ch
JOIN
(
SELECT communication_id, MAX(created_at) max_time, new_status_id
FROM Communications_History
GROUP BY communication_id
) ch2
ON ch.communication_id = ch2.communication_id AND ch.created_at = ch2.max_time
SET ch.new_status_id = ch2.new_status_id;
I have a MySQL DB and in it there's a table with activity logs of employees.
+-------------------------------------------------+
| log_id | employee_id | date_time | action_type |
+-------------------------------------------------+
| 1 | 1 | 2015/02/03 | action1 |
| 2 | 2 | 2015/02/01 | action1 |
| 3 | 2 | 2017/01/02 | action2 |
| 4 | 3 | 2016/02/12 | action1 |
| 5 | 1 | 2016/10/12 | action2 |
+-------------------------------------------------+
And I would need 2 queries. First, to get for every employee his last action. So from this example table I would need to get row 3,4 and 5 with all columns. And second, get the latest action only for specified employee.
Any ideas how to achieve this? I'm using Spring Data JPA, but raw SQL Query would be also great.
Thank you in advance.
Ready for a fred ed...
SELECT x.*
FROM my_table x
JOIN
( SELECT employee_id
, MAX(date_time) date_time
FROM my_table
GROUP
BY employee_id
) y
ON y.employee_id = x.employee_id
AND y.date_time = x.date_time;
For your first query. Simply
SELECT t1.*
FROM tableName t1
WHERE t1.log_id = (SELECT MAX(t2.log_id)
FROM tableName t2
WHERE t2.employee_id = t1.employee_id)
For the second one
SELECT t1.*
FROM tableName t1
WHERE t1.employee_id=X and t1.log_id = (SELECT MAX(t2.log_id)
FROM tableName t2
WHERE t2.employee_id = t1.employee_id);
You can get the expected output by doing a self join
select a.*
from demo a
left join demo b on a.employee_id = b.employee_id
and a.date_time < b.date_time
where b.employee_id is null
Note it may return multiple rows for single employee if there are rows with same date_time you might need a CASE statement and another attribute to decide which row should be picked to handle this kind of situation
Demo
Print not found when there is no data found in database. For example in my database I do not have 56443 therefore it should print 'not found'
SELECT uid, (CASE WHEN (u.uid = null) THEN 'not found' ELSE 'found' END) as result
FROM (SELECT uid
FROM users
WHERE uid IN (1,2,56443,3)) as u;
Getting result as follows
+--------+--------+
| uid | result|
+--------+--------+
| 1 | found |
| 2 | found |
| 3 | found |
+--------+--------+
I am also expecting not found row with 56443
You need to use a different approach. You will need to create a inline view with all the values using the UNION ALL, and then left join it with the users table:
SQL Fiddle
Query 1:
SELECT a.uid, (CASE WHEN (u.uid is null) THEN 'not found' ELSE 'found' END) as result
FROM (select 1 as UID FROM dual
UNION ALL
select 2 as UID FROM dual
UNION ALL
select 56443 as UID FROM dual
UNION ALL
select 3 as UID FROM dual) as a
LEFT JOIN users u on a.uid = u.uid
[Results]:
| UID | result |
|-------|-----------|
| 1 | found |
| 2 | found |
| 3 | found |
| 56443 | not found |
That is because you are comparing a value with null aka. unknown. Always use the IS operator when comparing to null values.
CASE WHEN (u.uid is null) THEN 'not found' ELSE 'found' END) as result
Try this instead (updated answer):
SELECT u2.uid, (CASE WHEN (u1.uid is null) THEN 'not found' ELSE 'found' END)
as result
FROM users u1
RIGHT JOIN
(select 1 as uid union all
select 2 as uid union all
select 3 as uid union all
select 56443 as uid
) u2
on u1.uid = u2.uid
I have tables as follows :
TABLE A
+-----+---------------+-------------+
| ID | DNR_DETAIL_ID | DESCRIPTION |
+-----+---------------+-------------+
| 1 | 1 | DESC A |
+-----+---------------+-------------+
| 2 | 2 | DESC B |
+-----+---------------+-------------+
| 3 | 3 | DESC C |
+-----+---------------+-------------+
TABLE B
+--------+---------------+
| DNR_ID | DNR_DETAIL_ID |
+------------------------+
| 1 | 1,2 |
+--------+---------------+
| 2 | 3 |
+--------+---------------+
As you can see, DNR_DETAIL_ID columns are common in both tables. What I want to do, left joining both tables with field values ( null or not )
THE RESULT SHOULD BE (IF DNR_ID = 1) :
+-------------+---------+
| DESCRIPTION | CHECKED |
+-------------+---------+
| DESC A | 1 |
+-------------+---------+
| DESC B | 1 |
+-------------+---------+
| DESC C | 0 |
+-------------+---------+
try this:
SELECT TA.description AS DESCRIPTION, CASE WHEN TB.checked IS NOT NULL THEN 1 ELSE 0 END AS CHECKED
FROM
(
select distinct description from TableA
) TA left join
(
SELECT description, 'checked' FROM TableA where dnt_detail_id in (
select dnr_detail_id from TableB where dnr_id = 1
)
)TB ON TB.description = TA.description
Try this using FIND_IN_SET()
SELECT
A.Description,
CASE WHEN B.DNR_ID IS NOT NULL THEN 1 ELSE 0 END as Checked
FROM A
LEFT JOIN B
ON FIND_IN_SET(A.DNR_DETAIL_ID, B.DNR_DETAIL_ID)
AND B.DNR_ID=1
SQLFiddle demo
SELECT a.DESCRIPTION,
CASE WHEN b.DNR_ID IS NOT NULL THEN 0 ELSE 1 END as CHECKED
FROM table_a a
LEFT JOIN table_b b
ON FIND_IN_SET(a.DNR_DETAIL_ID, b.DNR_DETAIL_ID)
Demo on sqlfiddle
Thank you so much guys. I have tried all of your suggestions but none of them work. Interesting thing is that code works well in sqlfiddle ( same schema and values ) but not working in local environment! Here is the query that working in local.
/**
* DNR_DETAIL_DESC IS TABLE A
* DNR_LIST IS TABLE B
*/
SELECT A.DNR_DETAIL_DESC,
CASE WHEN B.DNR_ID IS NOT NULL THEN 1 ELSE 0 END AS CHECKED
FROM MD_DNR_DETAIL A
LEFT JOIN (SELECT * FROM DNR_LIST WHERE DNR_ID = 1) AS B
ON FIND_IN_SET(A.DNR_DETAILT_ID, B.DNR_DETAIL_ID)
You can write it many ways, but here is the best way:
SELECT
MD_DNR_DETAIL.DNR_DETAIL_DESC as DESCRIPTION,
CASE WHEN DNR_LIST.DNR_ID IS NOT NULL THEN 1 ELSE 0 END AS CHECKED
FROM MD_DNR_DETAIL
LEFT JOIN DNR_LIST
ON FIND_IN_SET(MD_DNR_DETAIL.DNR_DETAILT_ID, DNR_LIST.DNR_DETAIL_ID)