I have this simple mysql query with join
Select
sp.PTPK, sp.EmployeeNamePK, sp.Half, sp.TaskPK, sp.TaskAssignCompletionId, sp.SwitchDate, sp.SpendDays, /*switch_person Table*/
pro.Name as ProjectName, pro.TeamLead /*Project Table*/
From switch_person sp
LEFT JOIN projects pro
ON pro.PK = sp.PTPK
Where sp.SwitchDate = '2019-03-01'
AND sp.Half =1
It is working correctly with one issue is that project unmatched record are not showing. I mean there are some non match records (projects name) which I am not getting from the project table. I know that it should be display as I am using left join.
How about...
SELECT sp.PTPK
, sp.EmployeeNamePK
, sp.Half
, sp.TaskPK
, sp.TaskAssignCompletionId
, sp.SwitchDate
, sp.SpendDays
, pro.Name ProjectName
, pro.TeamLead
FROM projects pro
LEFT
JOIN switch_person sp
ON pro.PK = sp.PTPK
AND sp.SwitchDate = '2019-03-01'
AND sp.Half = 1
...?
Updated after you last commment.
If indeed you want to always display the project data, I think you would probably be better served with a left join. Besides that, if the problem is performance, I suggest you:
Add an index to your switch_person table
Create a Stored procedure (SP) for your query
Like this:
CREATE INDEX mydataindex ON switch_person(PTPK, SwitchDate, Half);
CREATE
PROCEDURE getmydata (IN filterdate date, IN half INT)
SELECT sp.PTPK
, sp.EmployeeNamePK
, sp.Half
, sp.TaskPK
, sp.TaskAssignCompletionId
, sp.SwitchDate
, sp.SpendDays
, pro.Name ProjectName
, pro.TeamLead
FROM projects pro
LEFT
JOIN switch_person sp
ON pro.PK = sp.PTPK
AND sp.SwitchDate = filterdate
AND sp.Half = half
ORDER BY
pro.Name;
Then, all you have to do is call that SP like this:
CALL getmydata ('2019-03-01', 1);
updated full code here
Related
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
I am having trouble with a SQL query. So in my project user can reserve a ride. I want to display reserved rides by users ID (passenger_id) but query returns all users (driver_id) advertisements when user reserved a ride only for one of drivers advertisements.
SELECT advertisement.id
, COUNT(review.driver_id) AS 'review_count'
, ROUND(AVG(review.mark) ,1) AS 'rating'
, users.unique_id
, users.name
, users.surname
, users.phone
, YEAR(CURDATE()) - YEAR(users.birthdate) AS age
, users.image
, advertisement.from_city
, advertisement.to_city
, users.car_name
, users.car_model
, users.car_make_year
, advertisement.number_of_places
, advertisement.price
, advertisement.datetime
, advertisement.info
FROM reserved_rides
JOIN advertisement
ON reserved_rides.driver_id = advertisement.user_id
LEFT
JOIN review
ON reserved_rides.driver_id = review.driver_id
JOIN users
ON reserved_rides.driver_id = users.unique_id
WHERE reserved_rides.passenger_id = ?
GROUP
BY advertisement.id
ORDER
BY advertisement.datetime ASC
What is going wrong here?
I hope replacing GROUP BY advertisement.id with GROUP BY reserved_rides.driver_idsolves your problem. cheers
Using Report Builder 3.0, I have a report using the following dataset:
Declare #Hierarchy nVarChar (1000) = EAC.GetHierarchy (#UserName, DEFAULT)
SELECT TOP(100)
CASE
WHEN #ShowSourceTime = 1 THEN SourceTime
ELSE Dateadd(Minute, #TimeZoneOffset, Time)
END as Time
,Warehouse.EventInfo.TimeZoneShortName
,Warehouse.EventInfo.Category
,Warehouse.EventInfo.[Action]
,Warehouse.EventInfo.[Result]
,Warehouse.EventInfo.Reason
,Warehouse.EventInfo.PersonId
,Warehouse.EventInfo.Title
,Warehouse.EventInfo.FirstName
,Warehouse.EventInfo.MiddleName
,Warehouse.EventInfo.LastName
,Warehouse.EventInfo.Suffix
,Warehouse.EventInfo.Nickname
,Warehouse.EventInfo.DoorName
,Warehouse.EventInfo.DoorBehaviorName
,Warehouse.EventInfo.EnterZone
,Warehouse.EventInfo.LeaveZone
,Warehouse.EventInfo.SiteCode
,Warehouse.EventInfo.CardCode
,Warehouse.EventInfo.SiteCode + '-' + Warehouse.EventInfo.CardCode as Badge
FROM
Warehouse.EventInfo
WHERE
Warehouse.EventInfo.[Time] Between #StartTime and #EndTime
AND (1 = #PersonIdExpr OR EventInfo.PersonId IN (#PersonId))
AND WareHouse.EventInfo.ZoneHierarchy LIKE #Hierarchy
order by Time
The dataset is calling the view below:
SELECT EAC.Event.CreatedUTC AS Time
,DATEADD(MINUTE, EAC.Event.CreatedUTCOffset
, EAC.Event.CreatedUTC) AS SourceTime
, EAC.TimeZoneMap.TimeZoneShortName
, EAC.EventClass.Name AS Class
, EAC.EventCategory.Name AS Category
, EAC.EventAction.Name AS Action
, EAC.EventResult.Name AS Result
, EAC.EventReason.Name AS Reason
, EAC.Person.Id AS PersonId
, EAC.Person.Title
, EAC.Person.FirstName
, EAC.Person.MiddleName
, EAC.Person.LastName
, EAC.Person.Suffix
, EAC.Person.DisplayName AS Nickname
, EAC.Door.Name AS DoorName
, Zone_1.Name AS EnterZone
, (SELECT TOP (1) Name
FROM EAC.Zone
WHERE (Id IN (EAC.Door.Zone1Id, EAC.Door.Zone2Id))
AND (Id <> EAC.Event.ZoneId)) AS LeaveZone
, EAC.DoorBehavior.Name AS DoorBehaviorName
, EAC.Event.CardCode
, EAC.Event.SiteCode
, ISNULL(EAC.Event.Alarmed, 0) AS AlarmType
, Zone_1.ZoneHierarchy
FROM EAC.Event
INNER JOIN EAC.EventType ON EAC.EventType.Id = EAC.Event.EventTypeId
LEFT OUTER JOIN EAC.EventClass ON EAC.EventClass.Id = EAC.Event.EventClassId
LEFT OUTER JOIN EAC.EventCategory ON EAC.EventCategory.Id = EAC.EventType.CategoryId
LEFT OUTER JOIN EAC.EventAction ON EAC.EventAction.Id = EAC.EventType.ActionId
LEFT OUTER JOIN EAC.EventResult ON EAC.EventResult.Id = EAC.EventType.ResultId
LEFT OUTER JOIN EAC.EventReason ON EAC.EventReason.Id = EAC.EventType.ReasonId
LEFT OUTER JOIN EAC.Person ON EAC.Person.Id = EAC.Event.PersonId
LEFT OUTER JOIN EAC.Door ON EAC.Door.Id = EAC.Event.DoorId
LEFT OUTER JOIN EAC.Zone AS Zone_1 ON Zone_1.Id = EAC.Event.ZoneId
LEFT OUTER JOIN EAC.DoorBehavior ON EAC.DoorBehavior.Id = EAC.Door.DoorBehaviorId
LEFT OUTER JOIN EAC.Credential ON EAC.Credential.Id = EAC.Event.CredentialId
LEFT OUTER JOIN EAC.WiegandCredential ON EAC.WiegandCredential.CredentialId = EAC.Credential.Id
LEFT OUTER JOIN EAC.TimeZoneMap on EAC.TimeZoneMap.Id = EAC.Door.TimeZoneMapId
The table it is querying has millions of records but in order to get anything to come back I limited it to 100 records but it still takes 15 minutes.
When I run the report I see this in the database:
Here is the execution plan:
Execution plan
What can I do to make this report run more efficiently?
with that much LEFT OUTER JOIN It is not surprising that your query runs slow. Each join introduces complexity to your code. Besides, LEFT|RIGHT [OUTER] JOIN is much slower then regular join since it has to do all the work of an INNER JOIN (regular join) plus the extra work of null-extending the results.
Also it is impossible to make comment or pinpoint the problem without seeing explain plan of the query. Possibly you have missing indexes on tables(s)
I am having around 2.5 lachs (250K) products and 2600 subcategories on magento application (community edition).
Query
SELECT 1 status
, e.entity_id
, e.type_id
, e.attribute_set_id
, cat_index.position AS cat_index_position
, e.name
, e.description
, e.short_description
, e.price
, e.special_price
, e.special_from_date
, e.special_to_date
, e.cost
, e.small_image
, e.thumbnail
, e.color
, e.color_value
, e.news_from_date
, e.news_to_date
, e.url_key
, e.required_options
, e.image_label
, e.small_image_label
, e.thumbnail_label
, e.msrp_enabled
, e.msrp_display_actual_price_type
, e.msrp
, e.tax_class_id
, e.price_type
, e.weight_type
, e.price_view
, e.shipment_type
, e.links_purchased_separately
, e.links_exist
, e.open_amount_min
, e.open_amount_max
, e.custom_h1
, e.awards
, e.region
, e.grape_type
, e.food_match
, e.udropship_vendor
, e.upc_barcode
, e.ean_barcode
, e.mpn
, e.size
, e.author
, e.format
, e.pagination
, e.publish_date
, price_index.price
, price_index.tax_class_id
, price_index.final_price
, IF(price_index.tier_price IS NOT NULL
, LEAST(price_index.min_price
, price_index.tier_price)
, price_index.min_price) AS minimal_price
, price_index.min_price
, price_index.max_price
, price_index.tier_price
FROM catalog_product_flat_1 e
JOIN catalog_category_product_index cat_index
ON cat_index.product_id = e.entity_id
AND cat_index.store_id = 1
AND cat_index.visibility IN(2,4)
AND cat_index.category_id = 163
JOIN catalog_product_index_price price_index
ON price_index.entity_id = e.entity_id
AND price_index.website_id = 1
AND price_index.customer_group_id = 0
GROUP
BY e.entity_id
ORDER
BY cat_index_position ASC
, cat_index.position ASC
LIMIT 15;
whenever accessing any products on this magento site it created a huge data under /tmp directory on theserver which is around 10 GB.
How can I fix this please suggest some solution.
Database size is 50 GB and server is nginx.
You are misusing GROUP BY. Please learn how it works. There's a misfeature in MySQL which allows you to misuse it. Unfortunately, queries that misuse it are very difficult to troubleshoot.
It is difficult to infer what you are trying to do from your query. When you're dealing with result sets of that size, it helps to know your intent.
You should know, if you don't already, that queries of the form
SELECT <<many columns>>
FROM large_table
JOIN another_large_table ON something
JOIN another_large_table ON something
ORDER BY some_arbitrary_column
LIMIT some_small_number
can be grossly inefficient because they have to generate an enormous result set, then sort the whole thing, then return the first results. The sort operation carries the whole result set with it. You could be instructing the MySQL server to sort a crore or two of rows (dozens of megarows).
It looks like you want the first fifteen results starting with the lowest cat_index.position value. Accordingly, you may be able to make your query faster by joining with an appropriate subset of the table you call cat_index, like so:
SELECT 1 status, many_other_columns
FROM catalog_product_flat_1 e
JOIN ( /* join only with fifteen lowest eligible position values in cat_index */
SELECT *
FROM catalog_category_product_index
WHERE store_id = 1
AND visibility IN(2,4)
AND category_id = 163
ORDER BY position ASC
LIMIT 15
) AS cat_index ON cat_index.product_id = e.entity_id
JOIN catalog_product_index_price price_index
ON price_index.entity_id = e.entity_id
AND price_index.website_id = 1
AND price_index.customer_group_id = 0
GROUP BY e.entity_id /*wrong!!*/
ORDER BY cat_index_position ASC, /* redundant!*/
cat_index.position ASC
LIMIT 15;
It's worth a try.
Are you have sufficient Hardware resources to run a big query and also please update you hardware configuration of server.
I almost have the data I want...but need help filtering it. (pic at bottom)
The query below returns all records with a status of Member-id5 but I need to filter that. Ex: If I did a simple query on ect. (exp_channel_titles) for author_id 323 I would get 5 results. Of those 5 results one row has status = 'Member-id5', another one has a status = 'complete' AND title = %Member% (that's the deciding factor, the row with complete and Member in it). If that row exist then its okay to grab the entry_id of row status = Member-id5 to use for looking up the data in ecd (exp_channel_data) with in it. Any idea on how i can do that? picture enclosed
SELECT
ect.entry_id
, ect.author_id
, ect.title
, ect.status
, ecd.field_id_13
, ecd.field_id_14
, ecd.field_id_15
, ecd.field_id_25
, ecd.field_id_27
, ecd.field_id_28
, ecd.field_id_29
, ecd.field_id_30
, ecd.field_id_31
, ecd.field_id_32
, ecd.field_id_33
, ecd.field_id_34
, ecd.field_id_35
, exm.email
FROM exp_channel_titles as ect
LEFT JOIN exp_channel_data as ecd
ON ecd.entry_id = ect.entry_id
LEFT JOIN exp_members as exm
ON exm.member_id = ect.author_id
WHERE ect.status = 'Members-id5'
The picture is just of a simple query done on exp_channel_titles, of 323 as author_id. its to show how there multiple results and what entry_id i'm trying to get in order to finish my query. entry_id 496 is what I want, and that based on 1. there is a row with %Member% and complete in it. And then row 496 has a status of Members-id5.
SELECT ...
FROM exp_channel_titles as ect
JOIN exp_channel_titles as ect2
ON (
ect2.author_id = ect.author_id
AND ect2.title LIKE '%Member%'
AND ect2.status = 'complete'
)
...
WHERE ect.status = 'Members-id5'