Remove duplicate rows from query based on value in one column - sql-server

I have a table (SQL Server) where I store the run status of all of our automated test cases and I'm trying to come up with an SQL query to retrieve the status per runid, but I'm running into some problems with it.
Example of data within the table:
KRUNID | KTIME | FK_TC_ID | NOPART | STATUS | ENV
-------+----------------+------------+--------+--------+-----
4180-2 | 20190109080000 | TC0001 | 123456 | Passed | INT
4180-2 | 20190109080100 | TC0002 | 123457 | Failed | INT
4180-2 | 20190109080200 | TC0003 | 123458 | Passed | INT
4180-2 | 20190109080400 | TC0002 | 123459 | Passed | INT
Right now, I have this query (the join statements are used to display the actual test case name and business domain):
SELECT KRUNID, TD_NAME, TS_NAME, FK_TC_ID, TC_DISPLAYNAME, NOPARTENAIRE,
ENV, STATUS FROM RU_RUNSTATUS
INNER JOIN TC_TESTCASES ON K_TC_ID = FK_TC_ID
INNER JOIN TS_TCSUBDOMAINS ON K_TS_ID = FK_TS_ID
INNER JOIN TD_TCDOMAINS on K_TD_ID = FK_TD_ID
WHERE KRUNID = '418-2'
ORDER BY FK_TS_ID, K_TC_ID
The query is basic and it works fine except that I will have 2 lines for TC0002 when I only want to have the last one based on KTIME (for various reasons I don't want to filter based on STATUS).
I haven't found the right way to modify my query to get the result I want. How can I do that?
Thanks

I think this article can be respond : Get top 1 row of each group
Look of your query with limit partioned by FK_TC_ID and ordered by KTIME
;WITH cte AS
(
SELECT FK_TS_ID, KRUNID, TD_NAME, TS_NAME, FK_TC_ID , TC_DISPLAYNAME, NOPARTENAIRE,
ENV, STATUS, ROW_NUMBER() OVER (PARTITION BY FK_TC_ID ORDER BY KTIME DESC) AS rn
FROM RU_RUNSTATUS
INNER JOIN TC_TESTCASES ON K_TC_ID = FK_TC_ID
INNER JOIN TS_TCSUBDOMAINS ON K_TS_ID = FK_TS_ID
INNER JOIN TD_TCDOMAINS on K_TD_ID = FK_TD_ID
WHERE KRUNID = '418-2'
)
SELECT *
FROM cte
WHERE rn = 1
ORDER BY FK_TS_ID, K_TC_ID

Related

Why is my total not coming up correctly, and how can I fix it?

I'm working on remaking an Access report in SSRS with data from a SQL Server.
In the report I have a matrix, and one of the values is SumOfPieces.
SumOfPieces is in my Query as sum(t1.pieces) as SumOfPieces.
Inside the table I get the correct row values by just using [SumOfPieces], but my total is not adding anything together. For example this is what I am getting:
Product | Facility | Shift/Line | Pieces
BFS | BRWP | A 1 | 65,000
BFS | MHWP | A 2 | 70,000
BFS | MHWP | B 2 | 80,000
________________________________________
Total | | | 70,000
For some reason it's giving me the middle value
The expression for the total is simply =Sum(fields!SumOfPieces.Value)
I tried different variations of something like this expression =Sum(avg(fields!SumPieces.Value,"Product1")
In Access this is accomplished with queries nested 4-5 deep.
For this field specifically it looks like
Original query t1 with t1.Pieces
Next query on t1 with t1.Pieces summed as t1.SumOfPieces
Next query joins t1 with others
The Access report just uses that SumOfPieces as the row value, and then a sum(SumOfPieces) for the total.
Sample of my Dataset Query:
SELECT
StaveHistorySummary.fk_Inspectors
,StaveHistorySummary.fk_InspectionSites
,StaveHistorySummary.fk_ProductionLines
,StaveHistorySummary.fk_ProductTypes
,StaveHistorySummary.DateMade
,StaveHistorySummary.[TimeStamp]
,StaveHistorySummary.StaveHistoryguid
,InspectionSites.SiteAbbr
,Inspectors.Name
,ProductTypes.Product
,ProductionLines.LineName
,CAST(sum(Millproduction.Pieces) as int) AS SumPieces
,CASE
WHEN SapEdgingInches IS NOT NULL THEN SapEdgingInches
WHEN HeartEdgingInches IS NOT NULL THEN HeartEdgingInches
WHEN BothEdgingInches IS NOT NULL THEN BothEdgingInches
WHEN SawnIncorrInches IS NOT NULL THEN SawnIncorrInches
WHEN EqualizedIncorrInches IS NOT NULL THEN EqualizedIncorrInches
WHEN SawnOKInches IS NOT NULL THEN SawnOKInches
END AS WIDTH
FROM
StaveHistorySummary
INNER JOIN ProductionLines
ON StaveHistorySummary.fk_ProductionLines = ProductionLines.ProductionLines_NDX
INNER JOIN InspectionSites
ON StaveHistorySummary.fk_InspectionSites = InspectionSites.InspectionSites_NDX
INNER JOIN ProductTypes
ON StaveHistorySummary.fk_ProductTypes = ProductTypes.ProductTypes_NDX
INNER JOIN Inspectors
ON StaveHistorySummary.fk_Inspectors = Inspectors.Inspectors_NDX
INNER JOIN MillProduction
ON inspectionsites.inspectionsites_ndx = MillProduction.fk_inspectionsites
AND productionlines.productionlines_ndx = MillProduction.fk_productionlines
AND producttypes.producttypes_ndx = millproduction.fk_producttypes
WHERE (CAST(CAST(stavehistorysummary.DateMade as date) as datetime) BETWEEN '6/16/2019' AND '6/22/2019')
AND (CAST(CAST(MillProduction.DateMade as date) as datetime) BETWEEN '6/16/2019' AND '6/22/2019')
GROUP BY
StaveHistorySummary.fk_Inspectors
,StaveHistorySummary.fk_InspectionSites
,StaveHistorySummary.fk_ProductionLines
,StaveHistorySummary.fk_ProductTypes
,StaveHistorySummary.DateMade
,StaveHistorySummary.[TimeStamp]
,StaveHistorySummary.StaveHistoryguid
,InspectionSites.SiteAbbr
,Inspectors.Name
,ProductTypes.Product
,ProductionLines.LineName
,CAST(sum(Millproduction.Pieces) as int) AS SumPieces
,CASE
WHEN SapEdgingInches IS NOT NULL THEN SapEdgingInches
WHEN HeartEdgingInches IS NOT NULL THEN HeartEdgingInches
WHEN BothEdgingInches IS NOT NULL THEN BothEdgingInches
WHEN SawnIncorrInches IS NOT NULL THEN SawnIncorrInches
WHEN EqualizedIncorrInches IS NOT NULL THEN EqualizedIncorrInches
WHEN SawnOKInches IS NOT NULL THEN SawnOKInches
END AS WIDTH

EF6 - Generating unneeded nested queries

I have the following tables:
MAIN_TBL:
Col1 | Col2 | Col3
------------------
A | B | C
D | E | F
And:
REF_TBL:
Ref1 | Ref2 | Ref3
------------------
A | G1 | Foo
D | G1 | Bar
Q | G2 | Xyz
I wish to write the following SQL query:
SELECT M.Col1
FROM MAIN_TBL M
LEFT JOIN REF_TBL R
ON R.Ref1 = M.Col1
AND R.Ref2 = 'G1'
WHERE M.Col3 = 'C'
I wrote the following LINQ query:
from main in dbContext.MAIN_TBL
join refr in dbContext.REF_TBL
on "G1" equals refr.Ref2
into refrLookup
from refr in refrLookup.DefaultIfEmpty()
where main.Col1 == refr.Col1
select main.Col1
And the generated SQL was:
SELECT
[MAIN_TBL].[Col1]
FROM (SELECT
[MAIN_TBL].[Col1] AS [Col1],
[MAIN_TBL].[Col2] AS [Col2],
[MAIN_TBL].[Col3] AS [Col3]
FROM [MAIN_TBL]) AS [Extent1]
INNER JOIN (SELECT
[REF_TBL].[Ref1] AS [Ref1],
[REF_TBL].[Ref2] AS [Ref2],
[REF_TBL].[Ref3] AS [Ref3]
FROM [REF_TBL]) AS [Extent2] ON [Extent1].[Col1] = [Extent2].[Ref1]
WHERE ('G1' = [Extent2].[DESCRIPTION]) AND ([Extent2].[Ref1] IS NOT NULL) AND CAST( [Extent1].[Col3] AS VARCHAR) = 'C') ...
Looks like it is nesting a query within another query, while I just want it to pull from the table. What am I doing wrong?
I may be wrong, but it looks like you don't do the same in linq query and sql query, especially on your left joining clause.
I would go for this, if you want something similar to your sql query.
from main in dbContext.MAIN_TBL.Where(x => x.Col3 == "C")
join refr in dbContext.REF_TBL
on new{n = "G1", c = main.Col1} equals new{n = refr.Ref2, c = refr.Col1}
into refrLookup
from r2 in refrLookup.DefaultIfEmpty()
select main.Col1
By the way, it doesn't make much sense to left join on a table which is not present in the select clause : you will just get multiple identical Col1 if there's more than one related item in the left joined table...

SELECT DISTINCT showing duplicate dates per customer email

I am trying to retrieve information for the past ten months, but am having a couple of errors. First, my query is getting data from as far back as 2013. Secondly, I am seeing duplicates in my results based on the PolEffDate field, like this:
EntityID | PolEffDate | EMail | CustNo | Producer | BusinessPhone
abcde-12345-fghij-67890 | 2013-09-24 | somewhere#email.com | 31000 | Bob Builder | 123-456-7890
abcde-12345-fghij-67890 | 2013-12-01 | somewhere#email.com | 31000 | Bob Builder | 123-456-7890
abcde-12345-fghij-67890 | 2014-09-24 | somewhere#email.com | 31000 | Bob Builder | 123-456-7890
Here is my SQL Query:
SELECT DISTINCT
CONVERT(VarChar(36), Customer.CustId) AS EntityID
, BasicPolInfo.PolEffDate, Customer.EMail, Customer.CustNo
, (isnull(Employee.Firstname + ' ','') + isnull(Employee.LastName,''))
AS Producer, Employee.BusFullPhone
FROM
Customer INNER JOIN BasicPolInfo ON Customer.CustId = BasicPolInfo.CustId INNER JOIN
Transaction ON BasicPolInfo.PolId = Transaction.PolId INNER JOIN
GeneralBranch ON Customer.GLBrnchCode = GeneralBranch.GLBrnchCode INNER JOIN
GeneralDepartment ON Customer.GLDeptCode = GeneralDepartment.GLDeptCode INNER JOIN
GeneralDivision ON Customer.GLDivCode = GeneralDivision.GLDivCode INNER JOIN
Employee ON BasicPolInfo.ExecCode = Employee.EmpCode
WHERE
BasicPolInfo.PolExpDate >= DATEADD(MONTH, -10,CONVERT(VARCHAR(11),GETDATE(),106))
AND BasicPolInfo.PolExpDate <= CONVERT(VARCHAR(11),GETDATE(),106)
AND Customer.Active = 'Y'
AND Customer.typeCust = 'P'
Thank you for the help. I will try my best to answer any questions.
Daniel, the duplication you are seeing is caused because you have multiple records in BasicPolInfo for each CustID value. You can confirm this by running the following query:
SELECT CustID, COUNT(*)
FROM BasicPolInfo
GROUP BY CustID
HAVING COUNT(*) > 1
Depending on your schema, this may not be an issue - after all, there is probably a perfectly legitimate reason for that! Multiple policies per Customer is my guess.
To resolve the duplication, I would recommend a GROUP BY with MIN() or MAX().
Your other issue, that of retrieving data from earlier dates, is because you are selecting the PolEffDate (presumably, policy effective date), but filtering the PolExpDate (presumably, policy expiration date). Which are you intending to use? Policies that have finished sometime in the last ten months could have started much earlier than that.
To resolve the wider date range, reference the same value in your SELECT and WHERE clauses.
Query below (using MAX() and PolExpDate):
SELECT
CONVERT(VarChar(36), Customer.CustId) AS EntityID,
MAX(BasicPolInfo.PolExpDate) AS PolExpDate, -- note that this is now PolExpDate
Customer.EMail,
Customer.CustNo,
(isnull(Employee.Firstname + ' ','') + isnull(Employee.LastName,'')) AS Producer,
Employee.BusFullPhone
FROM
Customer INNER JOIN
BasicPolInfo ON Customer.CustId = BasicPolInfo.CustId INNER JOIN
[Transaction] ON BasicPolInfo.PolId = [Transaction].PolId INNER JOIN
GeneralBranch ON Customer.GLBrnchCode = GeneralBranch.GLBrnchCode INNER JOIN
GeneralDepartment ON Customer.GLDeptCode = GeneralDepartment.GLDeptCode INNER JOIN
GeneralDivision ON Customer.GLDivCode = GeneralDivision.GLDivCode INNER JOIN
Employee ON BasicPolInfo.ExecCode = Employee.EmpCode
WHERE
BasicPolInfo.PolExpDate >= DATEADD(MONTH, -10,CONVERT(VARCHAR(11),GETDATE(),106))
AND BasicPolInfo.PolExpDate <= CONVERT(VARCHAR(11),GETDATE(),106)
AND Customer.Active = 'Y'
AND Customer.typeCust = 'P'
GROUP BY
CONVERT(VarChar(36), Customer.CustId),
Customer.EMail,
Customer.CustNo,
(isnull(Employee.Firstname + ' ','') + isnull(Employee.LastName,'')),
Employee.BusFullPhone

referencing three columns to same column in another table in sql server 2000

I have a question on SQL Server 2000, i need to get an report from database. I have database called Automation where it contains set of tables to handle the queries of ticketing process of our application.
I need to extract a report from database that should contain ticket number and user information like who has entered, received, edited , reviewed that ticket.
I need these fields from the database
Ticketnumber
billnumber
companyname
enteredby(username)
entereddate
recievedby(username)
recieveddate
editedby(Employeename)
editeddate
reviewedby(ReviewerName)
revieweddate
postedby(Managername)
posteddate
I have three tables
1> VPP_VendorBilldetails
BillentryID | ticketnumber | billnumber | VENDORNAME,BILLNUMBER,COSTCENTERNAME,BILLAMOUNT,TICKETDATE,BILLDATE | companyID(not companyname) | billdate | Enteredby(userid)| entereddate | recievedby(userid) | recieveddate | editedby(userid) | editeddate | reviewedby(userid) | revieweddate | postedby(userid) | posteddate
2> Users
UserID | employeeID | employeename |loginID| Password | usertype | status
3> VPP_ClientCompanyDetails :
companyid | companyname | companyaddress | status
I have written this query, but I am getting same employee name for all three categories :
SELECT CLIENTCOMPANYNAME, TICKETNUMBER,VENDORNAME,BILLNUMBER,COSTCENTERNAME,BILLAMOUNT,TICKETDATE,BILLDATE,
RECIEVEDDATE,EMPLOYEENAME AS EXECUTIVENAME,
VPP_VENDORBILLDETAILS.MODIFIEDDATE,
EMPLOYEENAME AS REVIEWERNAME,EMPLOYEENAME AS POSTEDBY,POSTEDDATE,ERRORCODE,
IMPACTCODE,ROOTCAUSE,REVIEWERREMARKS
FROM
VPP_VENDORBILLDETAILS
INNER JOIN
VPP_CLIENTCOMPANYDETAILS
ON VPP_VENDORBILLDETAILS.BILLENTEREDCOMPANYID = VPP_CLIENTCOMPANYDETAILS.CLIENTCOMPANYID
INNER JOIN USERS
ON VPP_VENDORBILLDETAILS.MODIFIEDBY = USERS.USERID
WHERE CONVERT(VARCHAR(12),CONVERT(DATETIME,POSTEDDATE,103),101)
BETWEEN CONVERT(DATETIME,CONVERT(VARCHAR(12),getdate()-7,100),101)
AND CONVERT(DATETIME,CONVERT(VARCHAR(12),getdate()-1,100),101)
AND VPP_CLIENTCOMPANYDETAILS.STATUS = 1 AND VPP_VENDORBILLDETAILS.STATUS = 1 AND USERS.STATUS = 1 AND ERRORCODE IS NOT NULL AND TALLYID IS NOT NULL
ORDER BY CLIENTCOMPANYNAME ASC
Please check it and help me on this
Please help me to extract the report the above said tables..
Try this :
SELECT CLIENTCOMPANYNAME, TICKETNUMBER,VENDORNAME,BILLNUMBER,COSTCENTERNAME,BILLAMOUNT,TICKETDATE,BILLDATE,
RECIEVEDDATE,U1.EMPLOYEENAME AS EXECUTIVENAME,
VPP_VENDORBILLDETAILS.MODIFIEDDATE,
U2.EMPLOYEENAME AS REVIEWERNAME,U3.EMPLOYEENAME AS POSTEDBY,POSTEDDATE,ERRORCODE,
IMPACTCODE,ROOTCAUSE,REVIEWERREMARKS
FROM
VPP_VENDORBILLDETAILS
INNER JOIN
VPP_CLIENTCOMPANYDETAILS
ON VPP_VENDORBILLDETAILS.BILLENTEREDCOMPANYID = VPP_CLIENTCOMPANYDETAILS.CLIENTCOMPANYID
INNER JOIN USERS U1
ON VPP_VENDORBILLDETAILS.recievedby = U1.USERID
INNER JOIN USERS U2
ON VPP_VENDORBILLDETAILS.MODIFIEDBY = U2.USERID
INNER JOIN USERS U3
ON VPP_VENDORBILLDETAILS.postedby = U3.USERID
WHERE CONVERT(VARCHAR(12),CONVERT(DATETIME,POSTEDDATE,103),101)
BETWEEN CONVERT(DATETIME,CONVERT(VARCHAR(12),getdate()-7,100),101)
AND CONVERT(DATETIME,CONVERT(VARCHAR(12),getdate()-1,100),101)
AND VPP_CLIENTCOMPANYDETAILS.STATUS = 1 AND VPP_VENDORBILLDETAILS.STATUS = 1 AND USERS.STATUS = 1 AND ERRORCODE IS NOT NULL AND TALLYID IS NOT NULL
ORDER BY CLIENTCOMPANYNAME ASC

How to effectively join 3 tables M:N

I have few tables:
Apps:
id | name | url_key
===================
1 | Hello World | hello-world
2 | Snake 2 | snake-2
Developers:
id | name | url_key
===================
1 | Mr. Robinson | mr-robinson
2 | Richard | richard
3 | Nokia | nokia
Apps-Developers-Assignment
app_id | developer_id
=====================
1 | 1
1 | 2
2 | 3
So as you may see, one app may have more than one developer.
What i actually need is to write a PostgreSQL query to select all apps with some usefull information about related developers.
e.g. sth like this:
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson> /and 1 more/
Snake 2 | 2-snake-2 | Nokia<3-nokia>
So if the app has one developer, just append the developer's name, url key and id to the app, if it has more developers, append the first and append the information of "how many developers are there".
And what's most important - i need to eventually filter the results (e.g. not return apps from some specified developer).
I know it can be solved by write first query for apps itself and then send next query per each row, but not the nice way, i think...
If i just simply JOIN the table:
SELECT * FROM apps a
LEFT JOIN apps_developers_assignment ada ON a.id = ada.app_id
LEFT JOIN developers d ON ada.developer_id = d.id
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson>
Hello World | 1-hello-world | Richard<2-richard>
Snake 2 | 2-snake-2 | Nokia<3-nokia>
It returns duplicate apps... and i don't know how to filter these results by developer (as i wrote above).
Assuming you only want to filter out one developer, you will need to pass a parameter. I am calling this parameter/variable #excludeDevId for this purpose.
I am much more familiar to T-SQL, so this may/will also need the equivalent syntax in Postgres. Also, I am leaving nulls as a result of the left join as null--from your output you probably want to COALESCE (probably some other output tweaks as well). This is off the cuff and untested, but should be enough to get you moving in the right direction at least:
SELECT
a.name AppName,
a.id AppId,
d.id DevId,
d.url_key Url,
d.name DevName,
CAST(agg.dev_count - 1 as VARCHAR) + ' more'
FROM
(
SELECT
MAX(ada.developer_id) first_dev_id,
COUNT(ada.developer_id) dev_count,
app_id
FROM
apps_developers_assignment ada
WHERE
d.id != #excludeDevId
GROUP BY
app_id
) agg
INNER JOIN apps a ON a.id = agg.app_id
LEFT JOIN developers d ON agg.developer_id = d.id
If you want to use a left join, you'll need to put your condition on the join, otherwise it'll crate an inner join and the rows that have null in won't get returned... try something like this:
SELECT * FROM apps a
LEFT JOIN apps_developers_assignment ada ON a.id = ada.app_id
AND ada.developerid = :devid
LEFT JOIN developers d ON ada.developer_id = d.id
WHERE a.id = :appid

Resources