I want to remove the duplicates column with the same id. I want to keep only the first one that shows up.
SELECT t.ticketId ,t.userIdOwner , t.ticketCreateDatetime , t.ticketExpectedEndDatetime , t.ticketUpdateDatetime, t.ticketUpdateBy, t.ticketLabel,t.statusTypeIdTicketState,t.statusTypeIdTicketType,t.statusTypeIdTicketModule,
c.clientLabel, c.clientLogoOnList ,s.taskLabel , s.statusTypeIdTaskCompletion
FROM ticket AS t
INNER JOIN client AS c
ON c.clientId = t.clientId
LEFT JOIN task AS s
ON s.ticketId = t.ticketId AND s.statusTypeIdTaskCompletion = (SELECT statusTypeId FROM statusType WHERE statusTypeCode = 'waitingTask' AND statusTypeTargetTable = 'statusTypeIdTaskCompletion' )
WHERE 1=1
AND t.ticketDeleteDatetime IS NULL
Here's my screen of results
Edit Image query all results
enter image description here
Edit Image of task structure table :
enter image description here
You probably have more tasks for each ticket with same statusType
so, if you don't care about different tasks, you can simply add a DISTINCT clause in your SELECT
SELECT DISTINCT
t.ticketId ,t.userIdOwner , t.ticketCreateDatetime , t.ticketExpectedEndDatetime ,
t.ticketUpdateDatetime, t.ticketUpdateBy, t.ticketLabel,t.statusTypeIdTicketState,
t.statusTypeIdTicketType,t.statusTypeIdTicketModule,
c.clientLabel, c.clientLogoOnList ,s.taskLabel , s.statusTypeIdTaskCompletion
FROM ticket AS t
INNER JOIN client AS c ON c.clientId = t.clientId
LEFT JOIN task AS s ON s.ticketId = t.ticketId AND s.statusTypeIdTaskCompletion = (
SELECT statusTypeId
FROM statusType
WHERE statusTypeCode = 'waitingTask'
AND statusTypeTargetTable = 'statusTypeIdTaskCompletion'
)
WHERE 1=1
AND t.ticketDeleteDatetime IS NULL
ok, after your edit, now we can see, that the problem is that more than one task is eligible for the ticket.
Unfortunaterly "the first that show up" is not a valid SQL statement (because the same query could give different results depending on different circumnstances).
So you have to decide wich one to keep, you need to decide a rule, a logic to keep one of the rows.
If you don't need the task label you can simply strip off that column and use the DISTINCT.
If you want to show a task label but don't mind which one, you can use MAX(s.taskLabel) and group by on all other columns.
If you want to keep the last task for that ticket you should provide informations about cronological order (a datetime column or an autoincrement column)
Example with MAX(taskLabel):
SELECT
t.ticketId,
t.userIdOwner,
t.ticketCreateDatetime,
t.ticketExpectedEndDatetime,
t.ticketUpdateDatetime,
t.ticketUpdateBy,
t.ticketLabel,
t.statusTypeIdTicketState,
t.statusTypeIdTicketType,
t.statusTypeIdTicketModule,
c.clientLabel,
c.clientLogoOnList,
s.taskLabel,
s.statusTypeIdTaskCompletion
FROM ticket AS t
INNER JOIN client AS c ON c.clientId = t.clientId
LEFT JOIN (
SELECT s.ticketId, MAX(s.taskLabel) AS taskLabel
FROM task AS s
WHERE s.statusTypeIdTaskCompletion = (
SELECT statusTypeId
FROM statusType
WHERE statusTypeCode = 'waitingTask'
AND statusTypeTargetTable = 'statusTypeIdTaskCompletion'
)
GROUP BY s.ticketId
) S ON s.ticketId = t.ticketId
WHERE 1=1
AND t.ticketDeleteDatetime IS NULL
Related
review table has store_idx, user_idx etc...
I want to create a query sentence that gets information about the store to which the user has bookmarked with the user_id value entered.
The query sentence I made is
select A.store_name
, A.store_img
, count(B.store_idx) as review_cnt
from board.store A
Left
Join board.review B
On A.store_idx is B.store_idx
where store_idx is (select A.store_idx from bookmark where user_id = ?)
However, nothing came out as a result.
Help me..
Please use below Query:
SELECT store_name
, store_img
, SUM(review_cnt) AS review_cnt
FROM
( SELECT DISTINCT A.store_name
, A.store_img
, CASE WHEN B.store_idx IS NULL THEN 0 ELSE 1 END AS review_cnt
FROM bookmark br
JOIN board.store A
ON A.store_idx = br.store_idx
LEFT
JOIN board.review B
ON A.store_idx = B.store_idx
WHERE br.user_id = ?
)T
The WHERE clause is obviously filtering out all rows. We can't do much about that. But your query is also lacking a GROUP BY, the table aliases can be improved, and the join condition is not correct.
So, try this version:
select s.store_name, s.store_img, count(b.store_idx) as review_cnt
from board.store s left join
board.review r
on s.store_idx = r.store_idx
where b.store_idx in (select b.store_idx
from bookmark b
where b.user_id = ?
);
Please find below a link to the table-structure I have set up and to the query I am running.
Link to tables and query.
The present result is that only the firstnames, lastnames and "education_finished" are showing. But all the option_id's and their related lang_values still show "NULL".
The desired result:
Any suggestions how to solve?
Below is the query that you are using:
SELECT d.pf_firstname, d.pf_lastname, f.field_id, fl.option_id,
d.pf_education_finished, fl.lang_value
FROM phpbb_profile_fields_data d
LEFT JOIN phpbb_profile_fields f
ON d.pf_education_finished = f.field_name
LEFT JOIN phpbb_profile_fields_lang fl
ON f.field_id = fl.field_id
ORDER BY d.pf_lastname ASC
The reason why you are getting null value is because of this condition:
LEFT JOIN phpbb_profile_fields f
ON d.pf_education_finished = f.field_name
You are trying to join on pf_education_finished (int) field of one table and field_name (int) field of another table. Also, there are no matching values (e.g. pf_education_finished contains numbers whereas field_nameis 'education finished').
If you want the query to return something then you need to join on field_id and phpbb_profile_fields needs to have some records with matching field id, e.g.:
SELECT d.pf_firstname, d.pf_lastname, f.field_id, fl.option_id,
d.pf_education_finished, fl.lang_value
FROM phpbb_profile_fields_data d
LEFT JOIN phpbb_profile_fields f
ON d.pf_education_finished = f.field_id
LEFT JOIN phpbb_profile_fields_lang fl
ON f.field_id = fl.field_id
ORDER BY d.pf_lastname ASC
Here's the updated SQL Fiddle.
SELECT d.pf_firstname, d.pf_lastname, f.field_id, fl.option_id,
d.pf_education_finished, fl.lang_value
FROM phpbb_profile_fields_lang fl
inner JOIN phpbb_profile_fields f
ON f.field_id = fl.field_id
inner JOIN phpbb_profile_fields_data d
ON f.field_id = fl.field_id
ORDER BY d.pf_lastname ASC
This is the optional query if you want to display data from 3-4 tables but in this query names are repeats as per the count of field_id present in phpbb_profile_fields_lang.
The exact solution you are looking is, when you have the same primary key in all the tables from which you are retrieving the data.
Thank you.
I am trying to write a query that uses a LEFT OUTER JOIN on three tables. I have complete the first part to join two tables but I am stuck on intergarting the third table.
What I need is the "Status" field for the NXLHR_Valid to be included in the first query.
Below are my to queries, how would I include the SECOND query into the FIRST query
FIRST QUERY
SELECT NXLHR_SequenceNo_default.SeqNo, NXLHR_SequenceNo_default.SeqHeader, NXLHR_SequenceNo_default.SeqText, NXLHR_Hist.UniqueID, NXLHR_Hist.Room, NXLHR_Hist.Status, NXLHR_Hist.Water, NXLHR_Hist.AuditBy
FROM NXLHR_SequenceNo_default
LEFT OUTER JOIN NXLHR_Hist
ON NXLHR_SequenceNo_default.SeqID = NXLHR_Hist.SeqID
AND NXLHR_Hist.UniqueID = 'NXLHR01031472477564'
WHERE NXLHR_SequenceNo_default.SeqActive = 1
ORDER BY NXLHR_SequenceNo_default.OrderID
SECOND QUERY
SELECT NXLHR_Valid.UniqueID, NXLHR_Valid.Status
FROM NXLHR_Valid
WHERE NXLHR_Valid.UniqueID = 'NXLHR01031472477564'
Any help would be great. Thank you for your time.
SELECT d.SeqNo
, d.SeqHeader
, d.SeqText
, h.UniqueID
, h.Room
, h.Status
, h.Water
, h.AuditBy
, v.Status
FROM NXLHR_SequenceNo_default d
LEFT
JOIN NXLHR_Hist h
ON h.SeqID = d.SeqID
AND h.UniqueID = 'NXLHR01031472477564'
LEFT
JOIN NXLHR_Valid v
ON v.UniqueID = h.UniqueID
WHERE d.SeqActive = 1
ORDER
BY d.OrderID
I have 3 tables
person (id, name)
area (id, number)
history (id, person_id, area_id, type, datetime)
In this tables I store the info which person had which area at a specific time. It is like a salesman travels in an area for a while and then he gets another area. He can also have multiple areas at a time.
history type = 'I' for CheckIn or 'O' for Checkout.
Example:
id person_id area_id type datetime
1 2 5 'O' '2011-12-01'
2 2 5 'I' '2011-12-31'
A person started traveling in area 5 at 2011-12-01 and gave it back on 2011-12-31.
Now I want to have a list of all the areas all persons have right now.
person1.name, area1.number, area2.number, area6.name
person2.name, area5.number, area9.number
....
The output could be like this too (it doesn't matter):
person1.name, area1.number
person1.name, area2.number
person1.name, area6.number
person2.name, area5.number
....
How can I do that?
This question is, indeed, quite tricky. You need a list of the entries in history where, for a given user and area, there is an 'O' record with no subsequent 'I' record. Working with just the history table, that translates to:
SELECT ho.person_id, ho.area_id, ho.type, MAX(ho.datetime)
FROM History AS ho
WHERE ho.type = 'O'
AND NOT EXISTS(SELECT *
FROM History AS hi
WHERE hi.person_id = ho.person_id
AND hi.area_id = ho.area_id
AND hi.type = 'I'
AND hi.datetime > ho.datetime
)
GROUP BY ho.person_id, ho.area_id, ho.type;
Then, since you're really only after the person's name and the area's number (though why the area number can't be the same as its ID I am not sure), you need to adapt slightly, joining with the extra two tables:
SELECT p.name, a.number
FROM History AS ho
JOIN Person AS p ON ho.person_id = p.id
JOIN Area AS a ON ho.area_id = a.id
WHERE ho.type = 'O'
AND NOT EXISTS(SELECT *
FROM History AS hi
WHERE hi.person_id = ho.person_id
AND hi.area_id = ho.area_id
AND hi.type = 'I'
AND hi.datetime > ho.datetime
);
The NOT EXISTS clause is a correlated sub-query; that tends to be inefficient. You might be able to recast it as a LEFT OUTER JOIN with appropriate join and filter conditions:
SELECT p.name, a.number
FROM History AS ho
JOIN Person AS p ON ho.person_id = p.id
JOIN Area AS a ON ho.area_id = a.id
LEFT OUTER JOIN History AS hi
ON hi.person_id = ho.person_id
AND hi.area_id = ho.area_id
AND hi.type = 'I'
AND hi.datetime > ho.datetime
WHERE ho.type = 'O'
AND hi.person_id IS NULL;
All SQL unverified.
You're looking for results where each row may have a different number of columns? I think you may want to look into GROUP_CONCAT()
SELECT p.`id`, GROUP_CONCAT(a.`number`, ',') AS `areas` FROM `person` a LEFT JOIN `history` h ON h.`person_id` = p.`id` LEFT JOIN `area` a ON a.`id` = h.`area_id`
I haven't tested this query, but I have used group concat in similar ways before. Naturally, you will want to tailor this to fit your needs. Of course, group concat will return a string so it will require post processing to use the data.
EDIT I thikn your question has been edited since I began responding. My query does not really fit your request anymore...
Try this:
select *
from person p
inner join history h on h.person_id = p.id
left outer join history h2 on h2.person_id = p.id and h2.area_id = h.area_id and h2.type = 'O'
inner join areas on a.id = h.area_id
where h2.person_id is null and h.type = 'I'
I'm having problems with an SQL query used to display custom profile fields and any (optional) corresponding values.
Here is the SQL query I'm using:
SELECT pf.`id`, pf.`name`, pv.`value` FROM `profile_fields` AS pf
LEFT JOIN `profile_values` AS pv ON (pf.`id` = pv.`field_id`)
WHERE (pf.`site_id` = '0' OR pf.`site_id` = '%d') AND (pv.`user_id` = '%d' OR pv.`user_id` IS NULL)
ORDER BY pf.`order` ASC
The problem I'm having is that any columns with no corresponding profile_values records are not shown at all, when they should show, but just with an empty value.
Many thanks!
Try moving the profile values conditions to the JOIN statement:
SELECT pf.`id`, pf.`name`, pv.`value` FROM `profile_fields` AS pf
LEFT JOIN `profile_values` AS pv ON (
pf.`id` = pv.`field_id` AND
(pv.`user_id` = '%d' OR pv.`user_id` IS NULL)
)
WHERE (pf.`site_id` = '0' OR pf.`site_id` = '%d')
ORDER BY pf.`order` ASC