I have this query:
SELECT work_orders.id,work_orders.create_datetime,work_orders.location,
work_orders.description,user_accounts.function as function,
user_accounts.name as username,work_order_states.name as state,
work_orders_history.state_id,max(work_order_states.id)
FROM `work_orders`
LEFT JOIN work_orders_history
on work_orders.id = work_orders_history.work_order_id
LEFT JOIN user_accounts
on work_orders.create_user_id = user_accounts.id
LEFT JOIN work_order_type
on work_orders_history.type_id = work_order_type.id
LEFT JOIN work_order_states
on work_orders_history.state_id = work_order_states.id
... and the result is this:
But what i want is only get the rows with max state_id.
I already tried various queries, but this is the best result I can get.
EDIT: Since it's more than 65k results it's hard to provide a fiddle. The desireable result is like this image:
Thanks in advance.
You appear to be very close in your query. You need to add a GROUP BY and take away one of your select columns.
SELECT work_orders.id,work_orders.create_datetime,work_orders.location,
work_orders.description,user_accounts.[function] as [function],
user_accounts.name as username,work_order_states.name as state,
max(work_order_states.id)
FROM `work_orders`
LEFT JOIN work_orders_history
on work_orders.id = work_orders_history.work_order_id
LEFT JOIN user_accounts
on work_orders.create_user_id = user_accounts.id
LEFT JOIN work_order_type
on work_orders_history.type_id = work_order_type.id
LEFT JOIN work_order_states
on work_orders_history.state_id = work_order_states.id
GROUP BY work_orders.id,work_orders.create_datetime,work_orders.location,
work_orders.description,user_accounts.function,
user_accounts.name,work_order_states.name
HAVING work_orders_states.ID = (SELECT MAX(state_id) FROM work_orders_history)
I think what you are looking for is the HAVING and GROUP BY clause combined..
SELECT work_orders.id,work_orders.create_datetime,work_orders.location,
work_orders.description,user_accounts.function as function,
user_accounts.name as username,work_order_states.name as state,
work_orders_history.state_id,max(work_order_states.id)
FROM `work_orders`
LEFT JOIN work_orders_history
on work_orders.id = work_orders_history.work_order_id
LEFT JOIN user_accounts
on work_orders.create_user_id = user_accounts.id
LEFT JOIN work_order_type
on work_orders_history.type_id = work_order_type.id
LEFT JOIN work_order_states
on work_orders_history.state_id = work_order_states.id
GROUP BY work_orders.id,work_orders.create_datetime,work_orders.location,
work_orders.description,user_accounts.function,
user_accounts.name,work_order_states.name,
work_orders_history.state_id
HAVING work_orders_history.state_id=max(work_order_states.id)
Related
I am trying to create a SQL query where I take in 3 tables, and count all the rows.
Unfortunately I can't seem to get a response from this query.
$sqlQuery ="SELECT COUNT(*)
tblCampaignLists.CampaignListId,
tblCampaignLists.ClientId,
tblCampaignLists.CampaignId,
tblCampaignLists.CampaignFilter,
tblClients.ClientName,
tblClients.ClientState,
tblClients.ClientCreationDate,
tblClients.ClientEmail,
tblClients.ClientAddressCounty,
tblCampaigns.CampaignName,
tblCampaigns.CampaignDescription,
tblCampaigns.OrganisationId,
tblCampaignFilters.FilterId,
tblCampaignFilters.Section,
tblCampaignFilters.TitleIds,
tblCampaignFilters.FeatureIds,
tblCampaignFilters.EditionIds,
tblCampaignFilters.NotInEditionId
FROM
tblCampaignLists
LEFT JOIN tblClients ON tblClients.ClientId = tblCampaignLists.ClientId
LEFT JOIN tblCampaigns ON tblCampaigns.CampaignId = tblCampaignLists.CampaignId
LEFT JOIN tblCampaignFilters ON tblCampaignFilters.FilterId = tblCampaignLists.CampaignFilter
What can I do to get the number of rows?
Only use count:
$sqlQuery ="SELECT COUNT(*)
FROM
tblCampaignLists
LEFT JOIN tblClients ON tblClients.ClientId = tblCampaignLists.ClientId
LEFT JOIN tblCampaigns ON tblCampaigns.CampaignId = tblCampaignLists.CampaignId
LEFT JOIN tblCampaignFilters ON tblCampaignFilters.FilterId = tblCampaignLists.CampaignFilter"
I am having issues with getting this double left join to get the listingspecificsListPrice, but that info exists in the table, cant figure out why it would not include it. This is my sql.
SELECT mls_subject_property.*, mls_images.imagePath, mls_forms_listing_specifics.listingspecificsListPrice
FROM mls_subject_property
LEFT JOIN mls_images ON mls_subject_property.mls_listingID = mls_images.mls_listingID
LEFT JOIN mls_forms_listing_specifics ON mls_forms_listing_specifics.mls_listingID = mls_subject_property.mls_listingID AND mls_images.imgOrder = 0
WHERE userID = 413
GROUP BY mls_subject_property.mls_listingID
The result comes out like this..
All of the other fields come back, but it doesnt seem to want to bring back those two items.
This is a picture of the other table, to show that the data does in fact exist.
The mls_images.imgOrder = 0 condition should be in the join with mls_images, not mls_forms_listing_specifics.
Don't use GROUP BY if you're not using any aggregation functions. Use SELECT DISTINCT to prevent duplicates.
SELECT DISTINCT mls_subject_property.*, mls_images.imagePath, mls_forms_listing_specifics.listingspecificsListPrice
FROM mls_subject_property
LEFT JOIN mls_images ON mls_subject_property.mls_listingID = mls_images.mls_listingID AND mls_images.imgOrder = 0
LEFT JOIN mls_forms_listing_specifics ON mls_forms_listing_specifics.mls_listingID = mls_subject_property.mls_listingID
WHERE userID = 413
A bit of a newbie question, probably an INNER JOIN with an "AS" statement, but I can't figure it out...
This is for a MYSQL based competition app. I want to select the "img_title" for both img_id1 and img_id2. I can't figure out how to do it and still see which title is assigned to the associated _id1 or _id2.
My tables:
competitions
comp_id
img_id1
img_id2
on_deck
img_id
img_title
Desired results:
comp_id | img_id1 | img_title1 |img_id2 | img_title2
You need a join for each image:
SELECT comp.comp_id, img1.img_id, img1.img_title, img2.img_id, img2.img_title
FROM competitions comp
INNER JOIN on_deck img1 ON img1.img_id = comp.img_id1
INNER JOIN on_deck img2 ON img2.img_id = comp.img_id2
LEFT JOIN if img_id1 or img_id2 can be NULL.
select comp_id, img_id1, b.img_title as img_title1,
img_id2, b2.img_title as img_title2
from competitions a
left outer join on_deck b on b.img_id = a.img_id1
left outer join on_deck b2 on b2.img_id = a.img_id2
switch let outer join to inner join if you want to exclude rows in competitions that do not have two matching img_ids
This query should give you the results you want. This also assumes that comp.img_id1 and comp.img_id2 are never NULL.
SELECT comp.comp_id
, comp.img_id1
, deck1.img_title AS img_title1
, comp.img_id2
, deck2.img_title AS img_title2
FROM competitions AS comp
JOIN on_deck deck1 ON comp.img_id1 = deck1.img_id
JOIN on_deck deck2 ON comp.img_id2 = deck2.img_id
If you have plan on having a NULL or empty string comp.img_id1 and/or comp.img_id2 fields, you'll need to do some left joins.
Is there a way that I can combine these two queries:
FIRST QUERY
select top 100
WORK.pzInsKey,
WORK.pyID,
PARTY.MacID,
PARTY.OtherPartyID,
PARTY.CustomerEmail,
ACCOUNT.AccountNumber,
ACCOUNT.AccountName,
ACCOUNT.AdviserCode,
ACCOUNT.AdviserName,
ACCOUNT.DealerCode,
ACCOUNT.DealerName,
ACCOUNT.PrimaryAccount,
ACCOUNT.ProductCategory,
ACCOUNT.ProductCode,
ACCOUNT.ProductDescription,
ACCOUNT.RegisteredState,
DOCUMENT.UDOCID
from
workTable WORK,
partyTable PARTY,
accountTable ACCOUNT,
documentTable DOCUMENT,
notesTable NOTES
where WORK.pzInsKey = PARTY.pxInsIndexedKey
and WORK.pzInsKey = ACCOUNT.pxInsIndexedKey
and WORK.pyID = DOCUMENT.CaseID
and SECOND QUERY
SELECT top 100
BusinessAreaTbl.businessarea,
ProcessTbl.process,
SubProcessTbl.subprocess
FROM workTable WORK
LEFT OUTER JOIN (SELECT DISTINCT Product_ID businessarea_id, Product businessarea from CaseTypesTable) BusinessAreaTbl
ON WORK.RequestBusinessArea#1 = BusinessAreaTbl.businessarea_id
LEFT OUTER JOIN (SELECT DISTINCT Process_ID, Process, Product_ID businessarea_id from CaseTypesTable) ProcessTbl
ON WORK.RequestProcess#1 = ProcessTbl.process_id
AND ProcessTbl.businessarea_id = WORK.RequestBusinessArea#1
LEFT OUTER JOIN (SELECT DISTINCT SubProcess_ID, SubProcess, Product_ID businessarea_id, Process_ID from CaseTypesTable) SubProcessTbl
ON WORK.RequestSubProcess#1 = SubProcessTbl.subprocess_id
AND SubProcessTbl.businessarea_id = WORK.RequestBusinessArea#1
AND SubProcessTbl.process_id = WORK.RequestProcess#1
It's basically two queries which produce separate results, but each query includes data from the workTable. In the 2nd query, the workTable data is derived from the CaseTypesTable.
I essentially just want the businessarea, process, and subprocess fields to be included with the results of the first query.
Thanks in advance for any help.
This should work:
(SELECT top 100
w.pzInsKey,
w.pyID,
p.MacID,
p.OtherPartyID,
p.CustomerEmail,
a.AccountNumber,
a.AccountName,
a.AdviserCode,
a.AdviserName,
a.DealerCode,
a.DealerName,
a.PrimaryAccount,
a.ProductCategory,
a.ProductCode,
a.ProductDescription,
a.RegisteredState,
d.UDOCID
FROM workTable w
LEFT JOIN partyTable p
ON w.pzInsKey = p.pxInsIndexedKey
LEFT JOIN accountTable a
ON w.pzInsKey = a.pxInsIndexedKey
LEFT JOIN documentTable d
ON w.pyID = d.CaseID)
UNION
(SELECT top 100
ba.businessarea,
pr.process,
spr.subprocess
FROM workTable w
LEFT OUTER JOIN (SELECT DISTINCT Product_ID businessarea_id, Product businessarea from CaseTypesTable) BusinessAreaTbl ba
ON w.RequestBusinessArea#1 = ba.businessarea_id
LEFT OUTER JOIN (SELECT DISTINCT Process_ID, Process, Product_ID businessarea_id from CaseTypesTable) ProcessTbl pr
ON w.RequestProcess#1 = pr.process_id
AND pr.businessarea_id = w.RequestBusinessArea#1
LEFT OUTER JOIN (SELECT DISTINCT SubProcess_ID, SubProcess, Product_ID businessarea_id, Process_ID from CaseTypesTable) SubProcessTbl spr
ON w.RequestSubProcess#1 = spr.subprocess_id
AND spr.businessarea_id = w.RequestBusinessArea#1
AND spr.process_id = w.RequestProcess#1))
Use the keyword UNION to combine two or more seperate SELECT statements.
I have the following SQL query
SELECT
DISTINCT
count("SiteTree_Live"."ID")
FROM
"SiteTree_Live"
LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "TourPage_Live" ON "TourPage_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "DepartureDate" ON "DepartureDate"."TourID" = "SiteTree_Live"."ID"
WHERE
("SiteTree_Live"."Locale" = 'en_AU')
AND ("SiteTree_Live"."ClassName" IN ('TourPage'))
AND ("DepartureDate"."DepartureDate" LIKE '2012-11%')
but it producing a wrong count as the query result. The total intented result this query is suppose to return should not be more than 245 but currently, its returning more than about "4569" results.
Thats is because of the JOIN on the "DepartureDate" table as the query returns the expected result when i remove the join from the "DepartureDate" table.
What modification do i need to make to my query to count the Macthes between "SiteTree_Live"."ID" and "DepartureDate"."TourID" whiles counting only the "SiteTree_Live"."ID" count excluding the Departure dates?
Any suggestions welcomed :)
THE ANSWER
SELECT
COUNT(DISTINCT SiteTree_Live.ID)
FROM
"SiteTree_Live" LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "TourPage_Live" ON "TourPage_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "DepartureDate" ON "DepartureDate"."TourID" = "SiteTree_Live"."ID"
WHERE
("SiteTree_Live"."Locale" = 'en_AU')
AND ("SiteTree_Live"."ClassName" IN ('TourPage'))
AND ("DepartureDate"."DepartureDate" LIKE '2013-03%')
Seems to give me the right result. Thanks for the tip #Michael Berkowski
Minor correction: if DepartureDate is a date-type, then the LIKE '2013-03% will force it to be coerced into a character type (this is a mysql feature) As a result, any indexes on DepartureDate will not be used, IIRC. Better use a plain range-query:
SELECT
COUNT(DISTINCT stl.ID)
FROM
SiteTree_Live stl
LEFT JOIN
DepartureDate dd ON dd.TourID = stl.ID
WHERE
stl.Locale = 'en_AU'
AND stl.ClassName = 'TourPage'
AND dd.DepartureDate >= '2013-03-01'
AND dd.DepartureDate < '2013-04-01'
;
Do this (You have a bunch of unneeded joins)
SELECT
COUNT(DISTINCT SiteTree_Live.ID)
FROM
`SiteTree_Live`
LEFT JOIN
`DepartureDate` ON `DepartureDate`.`TourID` = `SiteTree_Live`.`ID`
WHERE
`SiteTree_Live`.`Locale` = 'en_AU'
AND `SiteTree_Live`.`ClassName` = 'TourPage'
AND `DepartureDate`.`DepartureDate` LIKE '2013-03%'
You could also do a GROUP BY:
SELECT
COUNT(SiteTree_Live.ID)
FROM
`SiteTree_Live`
LEFT JOIN
`DepartureDate` ON `DepartureDate`.`TourID` = `SiteTree_Live`.`ID`
WHERE
`SiteTree_Live`.`Locale` = 'en_AU'
AND `SiteTree_Live`.`ClassName` = 'TourPage'
AND `DepartureDate`.`DepartureDate` LIKE '2013-03%'
GROUP BY
SiteTree_Live.ID