I have a SQL Query giving me a list of double records in my database.
select periodid, itemid from periodscore
group by periodid, itemid
having count(*) > 1
This works as expected, but now I would like to retrieve additional fields of these records (such as date last updated etc). So I tried:
select * from periodscore where periodscoreid in
(select periodscoreid from periodscore
group by periodid, itemid
having count(*) > 1)
Of course this doesn't work and gives me the error:
Column 'periodscore.PeriodScoreID' is
invalid in the select list because it
is not contained in either an
aggregate function or the GROUP BY
clause.
How can I retrieve the extra fields in this query?
select ps.*
from periodscore ps
inner join (
select periodid, itemid
from periodscore
group by periodid, itemid
having count(*) > 1
) psm on ps.periodid = psm.periodid and ps.itemid = psm.itemid
select p1.* from periodscore p1 JOIN
(select periodid, itemid from periodscore
group by periodid, itemid
having count(*) > 1) p2
ON (p1.periodId = p2.periodId
AND p1.itemid = p2.itemid)
if periodid or item have null values then
select p1.* from periodscore p1 JOIN
(select periodid, itemid from periodscore
group by periodid, itemid
having count(*) > 1) p2
ON (IFNULL(p1.periodId,0) = IFNULL(p2.periodId,0))
AND IFNULL(p1.itemid,0) = IFNULL(p2.itemid,0))
Related
I have a table with columns ID, WorkingDate and AmountReceived where data is show as
ID WorkingDate AmountReceived
-------------------------------------
1 13/April/2021 201999.01
2 14/Arpil/2021 1099.02
Now, I am trying to show it like
13/April/2021 14/April/2021 15/April/2021
--------------------------------------------------
201999.01 1099.02 102.09
I tried this
select AmountReceived, WorkingDate
from Orders o
select distinct o.WorkingDate, sum(AmountReceived) over (partition by WorkingDate) as total
from Orders o
group by WorkingDate, AmountReceived
But it throws an aggregate error.
Using PIVOT operator, you can achieve what you want
select *
from
(
select o.WorkingDate, o.AmountReceived
from Orders o
) o
pivot
(
sum(AmountReceived)
for WorkingDate in ([2021-04-13], [2021-04-14], [2021-04-15])
) p
I have this query:
DECLARE #startTime DATETIME = DATEADD(MINUTE, -100, GETDATE()) --StartTime
SELECT
COUNT(*) Frecuency, mes.receivedqty AS Qty, ac.item AS Item
FROM
mesReservationReceipts mes (nolock)
INNER JOIN
ACCS_Reservation ac (nolock) ON ac.IDReservation = mes.idReservation
WHERE
ac.item IN (SELECT ac2.item
FROM mesReservationReceipts m2
INNER JOIN ACCS_Reservation ac2 ON ac2.IDReservation = m2.idReservation
WHERE m2.receivedate > #startTime)
GROUP BY
mes.receivedqty, ac.item
I get this result, but only I want the yellow highlighted rows - how can I get those? Please help!:
Note: I tried with MAX(Frequency) but that does not work because it should be grouped by the qty, and its the same case. I put a MAX(Qty), but for example, if the Qty is more than Statistic, add in the table result (and I only want the real statistic qty).
You can write something like this
SELECT * FROM(SELECT Frequency,Receivedqty,Item,
ROW_NUMBER() OVER(Partition by Item ORDER BY Quantity desc) as RowId
FROM (
----your query-----
))as q
Where q.RowId = 1
You can use row_number() to get the highest amount in each column. Then filter:
select item, Frecuency, qty
from (select ac.item as Item, count(*) as Frecuency, mes.receivedqty as Qty,
row_number() over (order by count(*) desc) as seqnum_f,
row_number() over (order by mes.receivedqty desc) as seqnum_r
from mesReservationReceipts mes join
ACCS_Reservation ac
on ac.IDReservation = mes.idReservation
where ac.item in (select ac2.item
from mesReservationReceipts m2 inner join
ACCS_Reservation ac2
on ac2.IDReservation = m2.idReservation
where m2.receivedate > #startTime
)
group by mes.receivedqty, ac.item
) ma
where 1 in (seqnum_f, seqnum_r);
Use rank() if you want duplicates, in the event that the highest values have duplicates.
This works perfectly until an order comes in where the stationID is not =2. My logic would be that sql searches where both conditions meet and display those results and not look where timeplaced is max then if stationid does not =2 display nothing which is what its doing.
SELECT OrderNo
FROM Orders
WHERE TimePlaced = (SELECT max(TimePlaced) FROM Orders)
AND StationID=2
Add your condition into the inner select too
SELECT OrderNo
FROM Orders
WHERE TimePlaced =
(
SELECT max(TimePlaced)
FROM Orders
WHERE StationID=2
)
AND StationID=2
But if you do not want to add the condition twice, then just "link" the inner select with the outer:
SELECT OrderNo
FROM Orders O
WHERE TimePlaced =
(
SELECT max(TimePlaced)
FROM Orders
WHERE StationID=O.StationID
)
AND StationID=2
Another way you could try would be with using a CTE and ROW_NUMBER:
;WITH OrdersCTE AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY StationID ORDER BY TimePlaced Desc) AS rn
FROM Orders
)
SELECT *
FROM OrdersCTE
WHERE rn = 1
AND StationID = 2
Can somebody please give me the correct query.
I have a table Item with two columns ItemNo and AliasItemNo.
I want to write a query to return me only those items that have more than one alias name
I'm trying to execute
select ItemNo, AliasItemNo
from Item
group by ItemNo, AliasItemNo
having count(ItemNo) > 1
order by ItemNo Asc
This query is not giving correct results.
Pls help
A subquery with the count is the way that works in all rdbms:
SELECT ItemNo, AliasItemNo FROM Item i1
WHERE (SELECT COUNT(*) FROM Item i2 WHERE i1.ItemNo=i2.ItemNo) > 1
ORDER BY ItemNo Asc
In SQL-Server >= 2005 you could also use COUNT(*) OVER (PARTITION BY ItemNo) in a CTE:
WITH CTE AS(
SELECT ItemNo,AliasItemNo,
Num=COUNT(*) OVER (PARTITION BY ItemNo)
FROM Item)
SELECT ItemNo, AliasItemNo FROM CTE
WHERE Num > 1
ORDER BY ItemNo Asc;
Demo: http://sqlfiddle.com/#!6/78d9c/9/1
This should work:
select ItemNo
from Item
group by ItemNo
having count(AliasItemNo) > 1
order by ItemNo Asc
You are counting ItemNo instead of AliasItemNo
There are a lot of ways to do this. Here's a couple of ways.
--using a sub query
SELECT
ItemNo,
AliasItemNo
FROM
Item INNER JOIN
(
SELECT
ItemNo
GROUP BY
ItemNo
HAVING
COUNT(AliasItemNo) > 1)
AS dupes
ON
Item.ItemNo = dupes.ItemNo
ORDER BY
Item.ItemNo ASC
--using CTE
;WITH
dupes AS
(
SELECT
ItemNo
GROUP BY
ItemNo
HAVING
COUNT(AliasItemNo) > 1
)
SELECT
ItemNo,
AliasItemNo
FROM
Item INNER JOIN dupes
ON
Item.ItemNo = dupes.ItemNo
ORDER BY
Item.ItemNo ASC
From the 1st query I am getting some value and from 2nd query I am getting some value. I want the sum of the two values.
Query 1:
select sum(EAmount) from EstimateAmount where pid='3' group by pid
Query 2:
select sum(OPEAmount) from OPEAmount where pid='3' group by pid
select
(select sum(EAmount) from EstimateAmount
where pid='3'
group by pid)
+
(select sum(OPEAmount) from OPEAmount
where pid='3'
group by pid)
Mitch solution is correct, I just want to add a more generic one for the cases when you need the sum for all pids and that can be extended to more aggregates:
with agg_EA as (
select pid, sum(EAmount) as sumEA
from EstimateAmount
group by pid)
, agg_OPEA as (
select pid, sum(OPEAmount) as sumOPE
from OPEAmount
group by pid)
select sumEA+sumOPE
from agg_EA
join agg_OPEA on agg_EA.pid = agg_OPE.pid
You can also use Union All and within a nested table when aggregating sums of sums
select sum(agg.Total) as GrandTotal
from ( select sum(EAmount) as Total from EstimateAmount where pid='3' group by pid
union all
select sum(OPEAmount) as Total from OPEAmount where pid='3' group by pid
) agg
Just join them:
SELECT sum(coalesce(e.EAmount,0) + coalesce(o.OPEAmount,0))
FROM EstimateAmount e
LEFT JOIN OPEAmount o ON o.pid = e.pid
WHERE e.pid = 3
GROUP BY e.pid