SQL Server, group by , aggregate into single result - sql

I have an SQL query that returns the data into multiple records (the first 4 records).
How can I combine the 4 rows above into one single record result?
The product where Type is null has only V1, V1_Status, V2 and V2_Status
In my query I already do:
SELECT Product, Max(Type), Max(V1), Max(V1_Status), Max(V2), Max(V2_Status), Max(V3), Max(V3_Status), Max(V4), Max(V4_Status), Max(V5), Max(V5_Status)
FROM Table
WHERE condition
GROUP BY Product, Type

You just need to not GROUP BY Type i.e.
SELECT Product,
Max(V1),
Max(V1_Status),
Max(V2),
Max(V2_Status),
Max(V3),
Max(V3_Status),
Max(V4),
Max(V4_Status),
Max(V5),
Max(V5_Status)
FROM Table
WHERE condition
GROUP BY Product

use row_number()
select * from
(
select t.*,row_number()over(partition by product order by v1 desc) rn
from table_name t
) a where a.rn=1

Related

SQL Oracle Find Max of count

I have this table called item:
| PERSON_id | ITEM_id |
|------------------|----------------|
|------CP2---------|-----A03--------|
|------CP2---------|-----A02--------|
|------HB3---------|-----A02--------|
|------BW4---------|-----A01--------|
I need an SQL statement that would output the person with the most Items. Not really sure where to start either.
I advice you to use inner query for this purpose. the inner query is going to include group by and order by statement. and outer query will select the first statement which has the most items.
SELECT * FROM
(
SELECT PERSON_ID, COUNT(*) FROM TABLE1
GROUP BY PERSON_ID
ORDER BY 2 DESC
)
WHERE ROWNUM = 1
here is the fiddler link : http://sqlfiddle.com/#!4/4c4228/5
Locating the maximum of an aggregated column requires more than a single calculation, so here you can use a "common table expression" (cte) to hold the result and then re-use that result in a where clause:
with cte as (
select
person_id
, count(item_id) count_items
from mytable
group by
person_id
)
select
*
from cte
where count_items = (select max(count_items) from cte)
Note, if more than one person shares the same maximum count; more than one row will be returned bu this query.

how to get latest date column records when result should be filtered with unique column name in sql?

I have table as below:
I want write a sql query to get output as below:
the query should select all the records from the table but, when multiple records have same Id column value then it should take only one record having latest Date.
E.g., Here Rudolf id 1211 is present three times in input---in output only one Rudolf record having date 06-12-2010 is selected. same thing with James.
I tried to write a query but it was not succssful. So, please help me to form a query string in sql.
Thanks in advance
You can partition your data over Date Desc and get the first row of each partition
SELECT A.Id, A.Name, A.Place, A.Date FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Date DESC) AS rn
FROM [Table]
) A WHERE A.rn = 1
you can use WITH TIES
select top 1 PERCENT WITH TIES * from t
order by (row_number() over(partition by id order by date desc))
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=280b7412b5c0c04c208f2914b44c7ce3
As i can see from your example, duplicate rows differ only in Date. If it's a case, then simple GROUP BY with MAX aggregate function will do the job for you.
SELECT Id, Name, Place, MAX(Date)
FROM [TABLE_NAME]
GROUP BY Id, Name, Place
Here is working example: http://sqlfiddle.com/#!18/7025e/2

Query to return rows with duplicate values based on other column

I have a table in SQL Server, the format is as follows:
I would want to get rows according to the following conditions:
If the rows have multiple but similar Customer_ID and Order_Number then return only those rows with maximum date
Otherwise, return the rest of the rows
So the result in this case will be row 3, 4 and 5.
Any idea on how to achieve this using SQL query? The table has no primary or unique key.
use window function row_number()
select *
from
(
select *,
row_number() over(partition by Customer_ID,Order_Number order by date desc) as rn
from your_table
) t where rn=1
or use co-relates subquery
select *
from t
where date in (
select max(date)
from t t1
where t1.Customer_ID=t.Customer_ID and t1.Order_Number=t.Order_Number
)

SQL. Is there any efficient way to find second lowest value?

I have the following table:
ItemID Price
1 10
2 20
3 12
4 10
5 11
I need to find the second lowest price. So far, I have a query that works, but i am not sure it is the most efficient query:
select min(price)
from table
where itemid not in
(select itemid
from table
where price=
(select min(price)
from table));
What if I have to find third OR fourth minimum price? I am not even mentioning other attributes and conditions... Is there any more efficient way to do this?
PS: note that minimum is not a unique value. For example, items 1 and 4 are both minimums. Simple ordering won't do.
SELECT MIN( price )
FROM table
WHERE price > ( SELECT MIN( price )
FROM table )
select price from table where price in (
select
distinct price
from
(select t.price,rownumber() over () as rownum from table t) as x
where x.rownum = 2 --or 3, 4, 5, etc
)
Not sure if this would be the fastest, but it would make it easier to select the second, third, etc... Just change the TOP value.
UPDATED
SELECT MIN(price)
FROM table
WHERE price NOT IN (SELECT DISTINCT TOP 1 price FROM table ORDER BY price)
To find out second minimum salary of an employee, you can use following:
select min(salary)
from table
where salary > (select min(salary) from table);
This is a good answer:
SELECT MIN( price )
FROM table
WHERE price > ( SELECT MIN( price )
FROM table )
Make sure when you do this that there is only 1 row in the subquery! (the part in brackets at the end).
For example if you want to use GROUP BY you will have to define even further using:
SELECT MIN( price )
FROM table te1
WHERE price > ( SELECT MIN( price )
FROM table te2 WHERE te1.brand = te2.brand)
GROUP BY brand
Because GROUP BY will give you multiple rows, otherwise you will get the error:
SQL Error [21000]: ERROR: more than one row returned by a subquery used as an expression
I guess a simplest way to do is using offset-fetch filter from standard sql, distinct is not necessary if you don't have repeat values in your column.
select distinct(price) from table
order by price
offset 1 row fetch first 1 row only;
no need to write complex subqueries....
In amazon redshift use limit-fetch instead for ex...
Select distinct(price) from table
order by price
limit 1
offset 1;
You can either use one of the following:-
select min(your_field) from your_table where your_field NOT IN (select distinct TOP 1 your_field from your_table ORDER BY your_field DESC)
OR
select top 1 ColumnName from TableName where ColumnName not in (select top 1 ColumnName from TableName order by ColumnName asc)
I think you can find the second minimum using LIMIT and ORDER BY
select max(price) as minimum from (select distinct(price) from tableName order by price asc limit 2 ) --or 3, 4, 5, etc
if you want to find third or fourth minimum and so on... you can find out by changing minimum number in limit. you can find using this statement.
You can use RANK functions,
it may seem complex query but similar results like other answers can be achieved with the same,
WITH Temp_table AS (SELECT ITEM_ID,PRICE,RANK() OVER (ORDER BY PRICE) AS
Rnk
FROM YOUR_TABLE_NAME)
SELECT ITEM_ID FROM Temp_table
WHERE Rnk=2;
Maybe u can check the min value first and then place a not or greater than the operator. This will eliminate the usage of a subquery but will require a two-step process
select min(price)
from table
where min(price) <> -- "the min price you previously got"

SQL Query to select top 2 for each value

I have a table with 3 columns, the data in column1 has repeating values and column 3 has totals, what I'd like to do is to return the top 2 totals for each value in column 1.
My query to create this table is below:
SELECT service,name, total
FROM [test].[dbo].[TestTable]
join test1.dbo.service
on substring(servan,0,4)=servicebn
where substring(servan,0,4)=servicebn and name <> testname
group by service,name,total
order by service,total desc
any help would be much appreciated
if you are using SQL Server 2005+, you can use Common Table Expression and Window Function.
WITH recordsList
AS
(
SELECT service, name, total,
DENSE_RANK() OVER (PARTITION BY service
ORDER BY total DESC) rn
FROM [test].[dbo].[TestTable]
INNER join test1.dbo.servd
on substring(servan,0,4)=servicebn
where substring(servan,0,4) = servicebn and
name <> testname
)
SELECT service, name, total
FROM recordsLIst
WHERE rn <= 2
As a side note, this query has poor in performance because it requires FULL TABLE SCAN on every table. The reason is because of the join condition substring(servan,0,4)=servicebn. It doesn't use index.