SQL Server 2012 Group only by one column - sql

I need to group only by one column
SQL Server 2012 query:
SELECT OrderID,Status,DateEdited
FROM orders
WHERE Status='Pending'
GROUP BY OrderID,Status,DateEdited
and the result is:
As you can see there are duplicate OrderId column values.
Works but it groups by OrderId,Status,DateEdit but what I need is that the OrderId would be unique in the results can I have something like:
SELECT OrderID,Status,DateEdited
FROM orders
WHERE Status='Pending'
GROUP BY OrderID

You have to use an aggregate function for status and DateEdited, to get distinct valeus for each grouped ORDERID. You can also use the ranking functions to do so like this:
WITH CTE
AS
(
SELECT
OrderID,
Status,
DateEdited,
ROW_NUMBER() OVER(PARTITION BY OrderID ORDER BY DateEdited DESC) rownum
FROM orders
WHERE Status='Pending'
)
SELECT
OrderID,
Status,
DateEdited
FROM CTE
WHERE rownum = 1;
This will give you distinct ORDERIDs. But which status and DateEdited to return for each grouped ORDERID?

Then you can do like this,
SELECT OrderID,'Pending' as Status,max(DateEdited)
FROM orders
WHERE Status='Pending'
GROUP BY OrderID
If you dont want to loose any record then you can go for
GROUP_CONCAT()
SELECT OrderID,'Pending' as Status,GROUP_CONCAT(DateEdited)
FROM orders
WHERE Status='Pending'
GROUP BY OrderID
Note: Am not sure whether you GROUP_CONCAT in sqlserver Incase it's not there
go for a function like that. :)

Related

How to select all columns with sum function

Assuming there is a table with 100 columns, how can I select all columns with a sum without having to type out all the columns?
For example something like this:
select *, sum(price) as sales
from table
group by *
order by date
try this
select table.* , t.sales from table
inner join (select id, sum(price) as sales from table group by id ) t
on table.id=t.id
order by date
But in general it is not recommended to use an stare in a select statement,
for example dont use * in table-valued function

SQL: Selecting multiple fields with one unique field based on most recent date

I'm attempting to write an SQL statement to select a unique part number based on the most recent date.
If I have just the two fields PartNo and ReceiveDate I could do:
"SELECT PartNo, Max(ReceiveDate) FROM Table GROUP BY PartNo;"
and this would return the unique PartNo and the most recent date.
The problem is that I also want to include the fields VendorName and Qty (But I just want PartNo to be unique). I've tried:
"SELECT PartNo, VendorName, Qty, Max(ReceiveDate) FROM Table GROUP BY PartNo;"
and
"SELECT PartNo, VendorName, Qty, Max(ReceiveDate) FROM Table GROUP BY PartNo, VendorName, Qty;"
I understand why these two SELECT statements are wrong, the first one doesn't run since VendorName and Qty aren't in the GROUP BY clause or part of an aggregate function, and in the second one it selects a unique record based on PartNo AND VendorName AND Qty, not just PartNo.
If someone could help me write the correct SQL statement that would be must appreciated. I'm using Microsoft Access which uses Jet SQL which is very similar to T-SQL.
I would suggest a correlated subquery:
SELECT t.*
FROM Table as t
WHERE t.ReceiveDate = (SELECT MAX(t2.ReceiveDate)
FROM Table as t2
WHERE t2.PartNo = t.PartNo
);
In particular, this can take advantage of an index on (PartNo, ReceiveDate).
If you mean, you don't care from which row Vendorname and Qty comes from (per partNo), then you can simply make them some aggregate function:
SELECT PartNo,
max(VendorName) as VendorName,
max(Qty) as Qty,
Max(ReceiveDate) as ReceiveDate
FROM [Table]
GROUP BY PartNo;
Probably a better approach would be to get those VendorName and Qty from the row with the last receive date (I assume that grouping return 1 date per PartNum):
select t.PartNo, t.VendorName, t.Qty, tmp.LastDate as ReceiveDate
from (SELECT PartNo, Max(ReceiveDate) as lastDate
FROM [Table]
GROUP BY PartNo) tmp
inner join [Table] t on t.PartNo = tmp.PartNo
where t.ReceiveDate = tmp.lastDate;
And I assume, no one really would name a table [Table].
Try to use crosstab query:
SELECT DISTINCT X.PartNo,X.MaxDate,Y.VendorName,Y.Qty FROM
(SELECT PartNo, Max(ReceiveDate)MaxDate FROM Table GROUP BY PartNo)X,
(SELECT PartNo, VendorName, Qty From Table)Y
WHERE X.PartNo=Y.PartNo

How to use DISTINCT and SUM in a same SQL query on MS SQL Express

I have a situation where I need to get DISTINCT values from column "note" and then get the SUM of "price" for above records.
I tried with different queries but none of them are working fine.
SELECT DISTINCT note ,price( select SUM (price) FROM [tableName] where Archived ='0'
SELECT sum(price),(SELECT DISTINCT note , price from [tableName] where Archived ='0')
In a nutshell I need to get the sum of prices for the distinct records.
Are you looking for group by?
SELECT note, SUM(price)
FROM [tableName]
WHERE Archived = '0'
GROUP BY note;
If you want the sum over ALL the records, just use window functions like this:
SELECT note, SUM(price) as note_sum, SUM(SUM(price)) OVER () as total_sum
FROM [tableName]
WHERE Archived = '0'
GROUP BY note;
Maxbe this will be one way to do it:
select distinct sum(price) over(partition by note), note
from tablename
where Archived = 0
Here is a demo on SQLServer
If I have understood you correctly you need distinct note values and only one sum for all of them ... then something like this:
select distinct note, (select sum(price) from tablename) sum_tot
from tablename
where Archived = 0
P.S. do add expected result....

In SQL, how to check for null condition on result with more than 1 value?

I want to get orderdate and productid in the result if that product has been ordered more than once on that day. If there is no product ordered more than once on any date, I want to return null in both columns.
I have figured out the result where the happy case of at least one product being ordered more than once exists in the table using the having clause. If I try using isnull or coalesce, I get an error since my final result has two values (date and productID)
select orderdate, prodid
from orders
group by orderdate, prodid
having count(*) > 1
On using isnull on the above query, I get this error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Use UNION ALL to get the row with nulls if there are no results from your query:
with cte as (
select orderdate, prodid
from orders
group by orderdate, prodid
having count(*)>1
)
select * from cte
union all
select null, null
where not exists (
select 1 from cte
)

get row with max from group by results

I have sql such as:
select
c.customerID, sum(o.orderCost)
from customer c, order o
where c.customerID=o.customerID
group by c.customerID;
This returns a list of
customerID, orderCost
where orderCost is the total cost of all orders the customer has made. I want to select the customer who has paid us the most (who has the highest orderCost). Do I need to create a nested query for this?
You need a nested query, but you don't have to access the tables twice if you use analytic functions.
select customerID, sumOrderCost from
(
select customerID, sumOrderCost,
rank() over (order by sumOrderCost desc) as rn
from (
select c.customerID, sum(o.orderCost) as sumOrderCost
from customer c, orders o
where c.customerID=o.customerID
group by c.customerID
)
)
where rn = 1;
The rank() function ranks the results from your original query by the sum() value, then you only pick those with the highest rank - that is, the row(s) with the highest total order cost.
If more than one customer has the same total order cost, this will return both. If that isn't what you want you'll have to decide how to determine which single result to use. If you want the lowest customer ID, for example, add that to the ranking function:
select customerID, sumOrderCost,
rank() over (order by sumOrderCost desc, customerID) as rn
You can adjust you original query to return other data instead, just for the ordering, and not include it in the outer select.
You need to create nested query for this.
Two queries.