sql server : how to get this result USING SQL SERVER QUERY? - sql

i have sql table like:
COL1 | COL2
A | P
A | Q
B | P
B | Q
I want a result like:
COL1 |COL2
A | P
B | Q

This would do it:
select COL1,
case
when COL1 = 'A' then MIN(COL2)
when COL1 = 'B' then MAX(COL2)
end
from #table
group by COL1
But the logic behind it is very limited to your sample result and wouldn't scale well. You need to provide more information. What is the logic behind getting the values for COL2?

Related

Select query eliminating unwanted rows

I'm new to SQLite and I am having trouble finding the solution.
I have TABLE1 with columns col1 and col2
col1 col2
-------------
a no
a no
a yes
b no
c yes
c no
d yes
I want no repetitions from col1 but prioritize col2 when having "yes"
I want something like this
col1 col2
-------------
a yes
b no
c yes
d yes
You may try the following:
Approach 1
You may use row_number to retrieve a row number ordered by col2 in descending order that may be used to filter your results eg.
SELECT
col1,
col2
FROM (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY col1
ORDER BY col2 DESC
) rn
FROM
my_table
) t
WHERE rn=1;
col1
col2
a
yes
b
no
c
yes
d
yes
Approach 2
or simply use a group by col1 with the MAX function. The group by will ensure that for each col1 value you will receive the MAX of col2 that is yes if available and no if not.
SELECT
col1,
MAX(col2) as col2
FROM
my_table
GROUP BY
col1;
col1
col2
a
yes
b
no
c
yes
d
yes
View working demo on DB Fiddle
ggordon's answer will work well enough, but just since a window function isn't strictly necessary I figured I'd pass another solution:
select distinct
a.col1,
ifnull(b.col2, 'no') col2
from my_table a
left join (
select distinct
col1,
col2
from my_table
where col2 = 'yes'
) b on a.col1 = b.col1
Output:
| col1 | col2 |
| ---- | ---- |
| a | yes |
| b | no |
| c | yes |
| d | yes |
You will first want to do a distinct select on column one. Then you will want to make a case statement which is essentially a if statement in other languages. The case needs to be if column 1 is yes return it. if it is not yes then return no. It would look something like this
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END;

SQL - Create a formatted ouput with placeholder rows

For reasons of our IT department, I am stuck doing this entirely within an SQL query.
Simplified, I have this as an input table:
And I need to create this:
And I am just not sure where to start with this. In my normal C# way of thinking its easy. Column1 is ordered, if the value in Col1 is new, then add a new row to the output and put the contents in column1 in the output. Then, whilst the contents of the input Column1 is unchanged, keep adding the contents of column2 to new rows.
In SQL... nope, I just cannot see the right way to start!
This is a presentation issue that can be easily done in the application or presentation layer. In SQL this can be clunky. The goal of a database is not to render a UI but to store and retrieve data fast and also efficiently, in order to serve as many clients as possible with the same hardware and software resources constraints.
The query that could do this can look like:
with
y as (
select col1, row_number() over(order by col1) as r1
from (select distinct col1 as col1 from t) x
),
z as (
select
t.col1, y.r1, t.col2,
row_number() over(partition by t.col1 order by t.col2) as r2
from t
join y on y.col1 = x.col1
)
select col1, col2
from (
select col1, null as col2, r1, 0 from y
union all
select null, col2, r1, r2 from z
) w
order by r1, r2
As you see, it looks clunky and bloated.
You need a header row for each group which will consist of col1 and null and all the rows of the table with null as col1.
You can do it with UNION ALL and conditional sorting:
select
case when t.col2 is null then t.col1 end col1,
t.col2
from (
select col1, col2 from tablename
union all
select distinct col1, null from tablename
) t
order by
t.col1,
case when t.col2 is null then 1 else 2 end,
t.col2
See the demo (for MySql but it is standard SQL).
Results:
| col1 | col2 |
| ---- | ----- |
| SetA | |
| | BH101 |
| | BH102 |
| | BH103 |
| SetB | |
| | BH201 |
| | BH202 |
| | BH203 |
I agree, formatting should be done outside of SQL, but if you have no choice, here is some SQL Server code that will generate your output
select *
from (
select top 100
case
when col2 is null then ' '+col1
else '' end as firstCol,
IsNull(col2,'') as Col2
from dbo.test t1
group by col1,col2 with rollup
order by col1,col2
) x
where x.firstcol is not null

How to add a column to a row in a select

Say I have this table
| Col |
-------
| ABC |
| DEF |
What query should I write to obtain this result (not literally this result, but a general way to do that)?
| Col | Col2 |
--------------
| ABC | 0 |
| ABC | 1 |
| DEF | 0 |
| DEF | 1 |
Unless I'm missing something, this should give you the results you're looking for:
Select Col, Col2
From YourTable
Cross Join (Select 0 As Col2 Union Select 1 As Col2) X
Order By Col, Col2
I would guess that you want to pair two columns, for each combination. Your question is vague and not specific to a problem. That's my assumption.
I guess this query could do:
Select Table1.Col1, Table2.Col2 from Table1 LEFT JOIN Table2 on 1=1
This way, you pair up every row from table1 with every row from table2.
Edit, without table2:
Select Table1.Col1, Constructed.Col1 from Table1 LEFT JOIN
(Select 1 as Col1 UNION Select 2 as Col1 UNION
Select 7 as Col1 UNION Select 14 as Col1) Constructed on 1=1
Can you test query, is this what you want?
select * from
(select col1, 0 b from table) table1
union all (select col1, 1 b from table) order by 1;

How to retrieve 2nd latest date from a table

I am trying to retrieve second latest date from a table. For example, consider this as my table:
COL1| COL2| COL3
---------------------
A | 1 | 25-JUN-14
B | 1 | 25-JUN-14
C | 1 | 25-JUN-14
A | 1 | 24-JUN-14
B | 1 | 24-JUN-14
C | 1 | 24-JUN-14
A | 1 | 23-JUN-14
B | 1 | 23-JUN-14
C | 1 | 23-JUN-14
I come up with this query which would get the result I want(2nd latest date).
SELECT sub.COL1, sub.COL2, MAX(sub.COL3)
FROM (SELECT t.COL1, t.COL2, t.COL3
FROM test t
GROUP BY t.COL1, t.COL2, t.COL3
HAVING MAX(t.COL3) < (
SELECT MAX(COL3)
FROM test sub
WHERE sub.COL1=t.COL1 AND sub.COL2=t.COL2
GROUP BY COL1, COL2)) sub
GROUP BY sub.COL1, sub.COL2;
As you can see it's big and messy statement with multiple nested sub queries just to get a 2nd latest date. I would love to learn an elegant solution for my problem rather that this mess. Appreciate your help.. :)
PS: I am not allowed to use 'WITH' command.. :(
If I understand correctly, you can do:
select t.*
from (select t.*,
dense_rank() over (order by col3 desc) as seqnum
from test t
) t
where seqnum = 2;
You can try like this:-
SELECT col1, col2, MAX(col3)
FROM TEST
WHERE col3 < (SELECT MAX(col3)
FROM tab1)
GROUP BY col1, col2;
Sql Fiddle Demo

Rotate one column and Select it comma seperated [duplicate]

This question already has answers here:
Inner Join Two Table, aggregating varchar fields
(2 answers)
Closed 8 years ago.
I have a table like this:
PK | COL1 | COL2
----------------
1 | A | a
2 | B | b
3 | C | c
4 | A | d
5 | A | e
6 | B | f
7 | C | g
8 | C | h
and I want to do an Select that I get the following result
COL1 | COL2
---------------
A | a,d,e
B | b,f
C | c,g,h
As I understand SQL at the moment I don't know how to do this without "programing" something extra e.q. with PL/SQL
But i search for an DBMS independent solution as good as it can be DBMS independent.
This is an Oracle (11.2) solution:
select col1,
listagg(col2, ',') within group (order by col1) as col2
from the_table
group by col1;
As you need this for other DBMS as well, this would be the Postgres solution:
select col1,
string_agg(col2, ',' order by col1) as col2
from the_table
group by col1;
For MySQL this would be:
select col1,
group_concat(col2 ORDER BY col1 SEPARATOR ',') as col2
from the_table
group by col1;
For a SQL Server solution, see Vijaykumar's answer.
try this !!
SELECT [col1],
SUBSTRING(d.col2,1, LEN(d.col2) - 1) col2
FROM
(
SELECT DISTINCT [col1]
FROM table1
) a
CROSS APPLY
(
SELECT [col2] + ', '
FROM table1 AS b
WHERE a.[col1] = b.[col1]
FOR XML PATH('')
) d (col2)