I have a query like below, but ShowRoomName and UnitNameare not shown in the result. How can I solve it?
SELECT A.ShowRoomId
, Sum(B.BasicAmount) AS TotalBasic
, Sum(B.HouseAmount) AS TotalHouseAmount
, Sum(B.MedicaleAmount) AS TotalMedicaleAmount
, Sum(B.ConvenceAmount) AS TotalConvenceAmount
, Sum(B.PhoneBillAmount) AS TotalPhoneBillAmount
, Sum(B.DirectorRemuneration) AS TotalDirectorRemuneration
, Sum(B.OthersAmount) AS TotalOthersAmount
FROM Employees A
OUTER APPLY (SELECT TOP 1 *
FROM EmployeeBasics B
WHERE ( A.EmployeeID = B.EmployeeID )
ORDER BY B.BasicUpdateDate DESC) AS B
OUTER APPLY (SELECT ShowRoomId
, ShowRoomName
, UnitId
FROM dbo.ShowRooms C
WHERE A.ShowRoomId = C.ShowRoomId) AS C
OUTER APPLY (SELECT UnitId
, UnitName
FROM dbo.Units D
WHERE C.UnitId = D.UnitId) AS D
GROUP BY A.SHowRoomId
use a more descriptive title when you ask a question. query not
working describes basically 99% of all questions.
your unit name and
showroomname dont appear because you dont select them...
I am guessing that you want something like this. Notice I changed your aliases into something meaningful. Using A, B, C is a bad habit for aliases. It is challenging to maintain code like that.
SELECT e.ShowRoomId
, Sum(eb.BasicAmount) AS TotalBasic
, Sum(eb.HouseAmount) AS TotalHouseAmount
, Sum(eb.MedicaleAmount) AS TotalMedicaleAmount
, Sum(eb.ConvenceAmount) AS TotalConvenceAmount
, Sum(eb.PhoneBillAmount) AS TotalPhoneBillAmount
, Sum(eb.DirectorRemuneration) AS TotalDirectorRemuneration
, Sum(eb.OthersAmount) AS TotalOthersAmount
, sr.ShowRoomName
, u.UnitName
FROM Employees e
OUTER APPLY
(
SELECT TOP 1 *
FROM EmployeeBasics eb1
WHERE e.EmployeeID = eb1.EmployeeID
ORDER BY eb1.BasicUpdateDate DESC
) AS eb
LEFT JOIN ShowRooms sr ON sr.ShowRoomId = e.ShowRoomId
LEFT JOIN Units u ON u.UnitID = sr.UnitID
GROUP BY e.SHowRoomId
, sr.ShowRoomName
, u.UnitName
Related
I have this query with 2 LEFT JOINS each with a sub-query.
The sub-queries should select the row with the latest date PointsChangeDate__c for a specific campaign e.g: PointsTypeCode__c = '1'.
Problem is that it is choosing what appears to be just random dates.
If I run just one JOIN / sub-query, then the result is correct, but when I add the 2nd JOIN / sub-query, then the results are incorrect and it seems to be pulling random dates.
I suspect my issue is with the type of JOIN I am using, but I cannot see why, because if I LEFT JOIN, then I am including all results (a._ContactKey) pulled from the first query and carrying that all the way through.
SELECT
a._ContactKey ContactId,
a.Full_Name_1__c Full_Name,
a.MC_Phone__c Mobile,
a.POSCustomerNumber__c POS_Customer_Number,
a.POSCustomerStatus__c POSCustomerStatus,
'IL' Locale,
a.Mobile_1__c Mobile_for_text,
g.TotalPoints__c TotalPoints_SourceMethod_1,
g.ValidUntil__c ValidUntil_SourceMethod_1,
g.date_1 PointsChangeDate__c_1,
h.TotalPoints__c TotalPoints_SourceMethod_2,
h.ValidUntil__c ValidUntil_SourceMethod_2,
h.date_2 PointsChangeDate__c_2
FROM
Contact_Salesforce AS a
LEFT JOIN
(SELECT
Contact__c,
TotalPoints__c,
ValidUntil__c,
MAX(PointsChangeDate__c) date_1
FROM
Member_points__c_Salesforce
WHERE
PointsTypeCode__c = '1'
GROUP BY Contact__c , TotalPoints__c , ValidUntil__c, PointsChangeDate__c) AS g ON a._ContactKey = g.Contact__c
LEFT JOIN
(SELECT Contact__c,
TotalPoints__c,
ValidUntil__c,
MAX(PointsChangeDate__c) date_2
FROM
Member_points__c_Salesforce
WHERE
PointsTypeCode__c = '2'
GROUP BY Contact__c , TotalPoints__c , ValidUntil__c, PointsChangeDate__c) AS h ON h.Contact__c = g.Contact__c
LEFT JOIN
SMS_Unsubscribe AS c ON REPLACE(CONCAT('972',
RIGHT(RTRIM(LTRIM(a.Mobile_1__c)), 9)),
'-',
'') = c.Mobile
LEFT JOIN
Member_Segments__c_Salesforce AS b ON b.Contact__c = a._ContactKey
WHERE
a.Mobile_1__c IS NOT NULL
AND c.Mobile IS NULL
AND a.POSCustomerStatus__c = '0'
AND b.IsActive__c = 'true'
GROUP BY a._ContactKey , a.Full_Name_1__c , a.MC_Phone__c , a.POSCustomerNumber__c , a.POSCustomerStatus__c , Locale , a.Mobile_1__c , a.Mobile_1__c , b.SegmentTypeID__c, b.SegmentTypeDescription__c , b.ToDate__c , g.TotalPoints__c , g.ValidUntil__c, g.date_1
,h.TotalPoints__c , h.ValidUntil__c, h.date_2
The problem situates itself at the 4th line of the SELECT statement: CASE WHEN ct.TransactionReason=622 THEN ABS(ct.netquantity) ELSE c.RealNetWeight END AS NetWeight
When I add this line to the statement, my grouping will change. Instead of returning one line it now gives me back the amount of lines of different c.realnetweight.
Problem is that I only want to return one line. Sort of like a coalesce that when there is a ct.transactionreason = 622, it should give me ABS(ct.netquantity), otherwise the c.realnetweight. Code can be found beneath, suggestions would be very helpful. Thanks.
SELECT CASE WHEN P.Wrapped = 1 THEN T.[Level]+1 ELSE T.[Level] END AS [Level]
, #CoilId AS CoilId
, c.SupplierCoilID
, CASE WHEN ct.TransactionReason=622 THEN ABS(ct.netquantity) ELSE c.RealNetWeight END AS NetWeight
, C.RealGrossWeight
, p1.Description
, p1.product
, s.StackID
, s.ProductID
, s.Weight
, P.Product
, P.Description AS 'ProductDescription'
, COUNT(t.BlankId) AS 'NumberOfBlanks'
, c1.Description as 'Status'
, pv.ProductionWeight
, pv.BlankWeight
, t.BlankStatus
FROM #Trace T
INNER JOIN SKUTraceability SKUT ON SKUT.SKUID = T.SKUID
INNER JOIN Stack s ON SKUT.StackID = s.StackID
INNER JOIN Product p ON s.ProductID = p.ProductID
INNER JOIN Coil c ON c.CoilID=#CoilId
INNER JOIN CoilTransaction ct on ct.CoilID=#CoilId
INNER JOIN Product p1 ON c.ProductID=p1.ProductID
INNER JOIN Code c1 ON t.BlankStatus=c1.codenumber AND c1.codetypeid=17
INNER JOIN #ProductVersion pv ON pv.ProductID=p.ProductId AND s.ProductVersion = pv.ProductVersion
WHERE t.BlankId IS NOT NULL
GROUP BY T.[Level]
, c.SupplierCoilID
, CASE WHEN ct.TransactionReason=622 THEN ABS(ct.netquantity) ELSE c.RealNetWeight END
, c.RealGrossWeight
, p1.Description
, p1.product
, s.StackID
, s.ProductID
, s.Weight
, p.Product
, p.Description
, c1.Description
, pv.ProductionWeight
, pv.BlankWeight
, p.Wrapped
, t.BlankStatus
Hard to answer without understanding your table structures however, it appears that CoilTransaction is some sort of transaction table, i.e. a single product can have many transactions.
In your SELECT query, the line causing you issues, is the only line that references your CoilTransaction table therefore I believe, the reason you're returning multiple rows is because you're grouping on a value that is not unique. Also, are transactions individual items because you seem to have a quantity column on the table.
In short, you can't get the grouping you want by including those columns from your transaction table. You would need to elaborate more on what you're trying to accomplish for us to give a more suitable solution. What does that line mean?
For at least one CoilID in table Coil, you will have more than one value in the field netquantity in the table CoilTransaction. This is what is causing the increase in the number of records returned when you include this field in your CASE statement.
I would recommend finding the netquantity value that you want from CoilTransaction in a CTE, and then bringing this in to your CASE statement. For example:
;WITH transaction_summary AS (
SELECT
ct.CoilID,
ct.TransactionReason,
MAX(ct.netquantity) -- choose your aggregate function here
FROM
CoilTransaction ct
GROUP BY
ct.CoilID,
ct.TransactionReason
)
...
I have 2 tables item and memo. In item, itemId is the PK and the itid is the FK. In memo the memID is the PK.
I created a view:
SELECT
dbo.memo.memID, dbo.memo.fullname, dbo.memo.company,
dbo.memo.department, dbo.memo.MRnum, dbo.memo.date,
dbo.memo.returndate, dbo.memo.remarks,
dbo.memo.issuedby, dbo.memo.picture, dbo.item.itemID AS Expr1,
dbo.item.Itemnumber, dbo.item.description, dbo.item.qty,
dbo.item.unitofmeasure, dbo.item.itid
FROM
dbo.memo
INNER JOIN
dbo.item ON dbo.memo.memID = dbo.item.itid
WHERE
(dbo.memo.department = N'tsd')
and output is this
this is the output
I just want 1 output of the fullname, company, department, MRnum, date , remarks, issuedby every multiple rows of item
enter image description here
Hope you understand . thank you
You can use DISTINCT in your query.
See below
SELECT DISTINCT dbo.memo.memID, dbo.memo.fullname, dbo.memo.company, dbo.memo.department, dbo.memo.MRnum, dbo.memo.date, dbo.memo.returndate, dbo.memo.remarks, dbo.memo.issuedby, dbo.memo.picture, dbo.item.itemID AS Expr1, dbo.item.Itemnumber, dbo.item.description, dbo.item.qty, dbo.item.unitofmeasure, dbo.item.itid
FROM dbo.memo
INNER JOIN dbo.item ON dbo.memo.memID = dbo.item.itid
WHERE (dbo.memo.department = N'tsd')
i just want , 1 output of the fullname, company, department, MRnum,
date , remarks, issuedby with multiple rows of item
You could do this, use group by on required columns and take top 1
SELECT TOP 1
dbo.memo.fullname ,
dbo.memo.company ,
dbo.memo.department ,
dbo.memo.MRnum ,
dbo.memo.date ,
dbo.memo.remarks ,
dbo.memo.issuedby
FROM dbo.memo
INNER JOIN dbo.item
ON dbo.memo.memID = dbo.item.itid
WHERE ( dbo.memo.department = N'tsd' )
GROUP BY dbo.memo.fullname ,
dbo.memo.company ,
dbo.memo.department ,
dbo.memo.MRnum ,
dbo.memo.date ,
dbo.memo.remarks ,
dbo.memo.issuedby
Also you can use TOP like below if you are certain you get all duplicate records.
SELECT TOP 1 dbo.memo.memID, dbo.memo.fullname, dbo.memo.company, dbo.memo.department, dbo.memo.MRnum, dbo.memo.date, dbo.memo.returndate, dbo.memo.remarks, dbo.memo.issuedby, dbo.memo.picture, dbo.item.itemID AS Expr1, dbo.item.Itemnumber, dbo.item.description, dbo.item.qty, dbo.item.unitofmeasure, dbo.item.itid
FROM dbo.memo
INNER JOIN dbo.item ON dbo.memo.memID = dbo.item.itid
WHERE (dbo.memo.department = N'tsd')
I am working on a dynamic query and I am a little unsure how to accomplish this task. It seems like something that would be common so I will use this as a learning experience.
My Structure has several tables. I have included a few of them for this example as once I can get the base query down, I can add on to it.
In my final query, the WHERE clause will be generated dynamically.
Here is a fiddle of my structure: http://sqlfiddle.com/#!6/2b104
In the inner select c. you will notice I have a column called localeID. I need to be able to query this in my outer WHERE clause.
For example, that localeID will link to the localeCodes table and from there, I have another table called locations. End result would be saying "Show me everything in North America". Well, we know localeID 8 = Utah and Utah is in North America (when joined to the locations table).
Here is the query to keep it with the OP:
SELECT a.[trainingEventID],
a.[teTitle],
a.[teSource],
a.[teType],
a.[teMedium],
a.[teFlag],
a.[teCreator],
a.[teCreated],
a.[tePOC],
a.[teDirector],
a.[teTeammateImpact],
a.[teCustomerImpact],
a.[teComplexity],
a.[intID],
a.[teNeededBy],
a.[approver],
a.[approvalDate],
(SELECT b.[trainingEventID],
b.[segmentDate],
b.[nonProdHrs],
(SELECT c.[segmentID],
c.[localeID],
c.[teammateCount],
c.[leaderCount]
FROM BS_TrainingEvent_SegmentDetails AS c
WHERE c.[segmentID] = b.teSegmentID
FOR XML PATH ('detail'), TYPE, ELEMENTS, ROOT ('details'))
FROM BS_TrainingEvent_Segments AS b
WHERE b.trainingEventID = a.[trainingEventID]
FOR XML PATH ('segment'), TYPE, ELEMENTS, ROOT ('segments'))
FROM BS_TrainingEvents AS a
--WHERE c.[localeID] = '8'
FOR XML PATH ('event'), TYPE, ELEMENTS, ROOT ('events');
How about we also join to those two subordinate tables so we can narrow the result set based on your c.localeID:
SELECT a.[trainingEventID],
a.[teTitle] ,
a.[teSource] ,
a.[teType] ,
a.[teMedium] ,
a.[teFlag] ,
a.[teCreator] ,
a.[teCreated] ,
a.[tePOC] ,
a.[teDirector] ,
a.[teTeammateImpact] ,
a.[teCustomerImpact] ,
a.[teComplexity] ,
a.[intID] ,
a.[teNeededBy] ,
a.[approver] ,
a.[approvalDate] ,
( SELECT b.[teSegmentID],
b.[trainingEventID] ,
b.[segmentDate] ,
b.[nonProdHrs] ,
( SELECT c.[segmentID] ,
c.[localeID] ,
c.[teammateCount] ,
c.[leaderCount]
FROM BS_TrainingEvent_SegmentDetails AS c
WHERE c.[segmentID] = b.teSegmentID
AND c.segmentID = tesd.SegmentID
FOR
XML PATH('detail') ,
TYPE ,
ELEMENTS ,
ROOT('details')
)
FROM BS_TrainingEvent_Segments AS b
WHERE b.trainingEventID = a.[trainingEventID]
AND b.trainingEventID = tes.trainingEventID
FOR
XML PATH('segment') ,
TYPE ,
ELEMENTS ,
ROOT('segments')
)
FROM BS_TrainingEvents a
INNER JOIN BS_TrainingEvent_Segments tes ON a.trainingEventID = tes.trainingeventID
INNER JOIN BS_TrainingEvent_SegmentDetails tesd ON tes.teSegmentID = tesd.SegmentID
INNER JOIN BS_LocaleCodes as locale ON tesd.localeID = locale.localeID
INNER JOIN BS_Locations as loc ON loc.location = locale.location
WHERE loc.[location] = 'Arizona'
FOR XML PATH('event') ,
TYPE ,
ELEMENTS ,
ROOT('events');
I have 2 sql tables named mtblAttendance and mtblLeave_Data.
I need to get the all dates from mtblLeave_Data when User was on leave depending on absent in mtblAttendance.
In my mtblAttendance for every leave there is a row, but if a user on leave for a period so there is no unique row, there are just two columns Leave_From and Leave_To (or it may be a single entry where Leave_From= Leave_To).
For getting the absent dates of user I wrote the query
USE [ILeave]
ALTER procedure [dbo].[Attendance_Report]
#Date1 datetime,
#Date2 datetime,
#User_Id nvarchar(50)
as begin
SELECT distinct
a.Sno,
a.[Login_Date],
a.[Week_Day],
a.[In_Time],
a.[Out_Time],
a.Attendance_Status,
a.Half_Full,
a.Leave_Type,
(convert(varchar(max),floor (abs(cast(datediff(mi, a.Out_Time, a.In_Time) AS int) / 60)))+ '.'+ convert(varchar(max),(abs(cast(datediff(mi, a.Out_Time, a.In_Time) AS int) % 60)))) as Hrs
, l.[Sno]
, l.[Leave_ID]
, l.[User_Id]
, l.[Dept_To]
, l.[Leave_Type]
, l.[Total_Leave_HR]
, l.[Leave_From]
, l.[Leave_To]
, l.[Leave_Half_Full]
, l.[Comments]
, l.[Leave_Status]
FROM
[mtblAttendance] a
LEFT JOIN [mtbl_Leave_Data] l
ON a.[Login_Date] BETWEEN l.[Leave_From] AND l.[Leave_To]
AND l.[User_Id] = a.[User_Id] where a.Login_Date between #Date1 and #Date2 and a.User_Id=#User_Id order by Login_Date
end
The following query should return the leave record assigned
SELECT
a.[Login_Date]
, l.[Sno]
, l.[Leave_ID]
, l.[User_Id]
, l.[Dept_To]
, l.[Leave_Type]
, l.[Total_Leave_HR]
, l.[Leave_From]
, l.[Leave_To]
, l.[Leave_Half_Full]
, l.[Comments]
, l.[Leave_Status]
FROM
[mtblAttendance] a
LEFT JOIN [mtbl_Leave_Data] l ON a.[Login_Date] BETWEEN l.[Leave_From] AND l.[Leave_To]
WHERE
a.User_Id = 'sasi'
AND a.Attendance_Status='A'
I put it into a fiddle, but with no data so all I can say is that the query parses.
As someone has previously stated, it is common to have tables with dates in, whereby queries requiring every date in a 2 year period can quickly be assessed.
Updated SQL:
SELECT DISTINCT
a.[Login_Date]
, l.[Sno]
, l.[Leave_ID]
, l.[User_Id]
, l.[Dept_To]
, l.[Leave_Type]
, l.[Total_Leave_HR]
, l.[Leave_From]
, l.[Leave_To]
, l.[Leave_Half_Full]
, l.[Comments]
, l.[Leave_Status]
FROM
[mtblAttendance] a
LEFT JOIN [mtbl_Leave_Data] l
ON a.[Login_Date] BETWEEN l.[Leave_From] AND l.[Leave_To]
AND l.[userId] = a.[user_id] -- Ensure only attendance/leave for the same user being linked
WHERE
a.User_Id = 'sasi'
AND a.Attendance_Status='A'
Join expressions aren't limited to using the equals sign. Use "between" in the join expression. Something along these (untested) lines should work.
select distinct A.Login_Date
from mtblAttendance A
inner join mtbl_Leave_Data L
on A.User_id = L.User_id
and A.Login_date between L.Leave_From and L.Leave_To
where A.User_Id = 'sasi' AND A.Attendance_Status='A'
Depending on what you're trying to do, you might need to change the inner join to a left outer join. A left outer join will preserve all login dates from mtblAttendance, regardless of whether they satisfy the join condition. (Those rows will be filtered by the WHERE clause, of course.)