To get different row values in different columns in a single row - sql

My table looks like this:
Param_id Param_value
------------------------
A 1
B 2
C 3
D 4
.... and so on. Now I want only the values of Param_id "A" and "B".
Now I want to get the param_value in two different columns instead of two different rows. But if I use IN clause it will return the result in two rows.
I want something like the below:
Param_value_1 Param_value_2
---------------------------------
1 2
I can't use listagg or pivot because they are not serving my purpose. Is there any other way to achieve this? I searched in Google but could not find any solution for this.

The old way of pivoting... Since you are looking for the parameter values for parameter_id in ('A', 'B'), it doesn't make much sense to name the resulting columns param_value_1 and param_value_2; why not param_value_a and param_value_b? (Otherwise what determines that 'A' is 1 and 'B' is 2, and not the other way around?)
So - back to the old way of pivoting (although I suspect PIVOT will work too, regardless of requirement - unless you are on Oracle 10 or lower):
select max(case when param_id = 'A' then param_value end) as param_value_a,
max(case when param_id = 'B' then param_value end) as param_value_b
from your_table;

Related

How to count when don't know specific types

I'm working on a table kind of like this:
id
type
1
A
2
A
3
B
4
C
5
C
I wanted to count the number of ids for each type, and get a table like this.
type_a
type_b
type_c
2
1
2
What I did was
SELECT
SUM(CASE WHEN type = 'A' THEN 1 ELSE 0 END) AS type_a,
SUM(CASE WHEN type = 'B' THEN 1 ELSE 0 END) AS type_b,
SUM(CASE WHEN type = 'C' THEN 1 ELSE 0 END) AS type_c
FROM myTable
My question is, if I don't know how many types are there, and can't specificly list all cases, how can I achieve it?
You are looking for "cross tabulation" or a "pivot table". I added tags.
However:
if I don't know how many types are there, and can't specifically list all cases, how can I achieve it?
Basically, that's impossible in a single SQL query because SQL demands to know the number of result columns at call time. It cannot return a dynamic number of columns on principle.
There are various workarounds with polymorphic types, or with a document type like json, jsonb, hstore or xml, or return arrays instead of individual columns ...
But to get exactly what you are asking for, an unknown number of dedicated columns, you need a two-step workflow. Like:
Build the query dynamically (determining the return type).
Execute it.
Related:
Dynamic alternative to pivot with CASE and GROUP BY
PostgreSQL Crosstab Query
That said, if your case is simple and you deal with a hand full of known types, you can just over-provision. With a faster crosstab() query, or with simple conditional aggregation like you have it, just more elegant and efficient with the aggregate FILTER clause:
SELECT count(*) FILTER (WHERE type = 'A') AS type_a
, count(*) FILTER (WHERE type = 'B') AS type_b
, count(*) FILTER (WHERE type = 'C') AS type_c
, count(*) FILTER (WHERE type = 'D') AS type_d
-- that's all folks!
FROM tbl;
Types with no entries report 0 (count() never returns NULL) which would be correct anyway.
Does not work for unknown types, obviously.
If I understand you correctly, all you want is a simple COUNT:
SELECT
type
,COUNT(id)
FROM myTable
GROUP BY type

Qualifying a column in a SQL select statement

I'm looking to generate a query that pulls from several tables. Most are rather straightforward and I can pull a value from a table directly but there is one table that is pivoted so that the value I want depends on the value in another column.
The table looks like the below:
ID Condition Value
1 Stage1 6
2 Stage2 9
3 Stage3 5
4 Stage4 2
So I'm looking to write a query that essentially "qualifies" the value I want by telling the table which condition.
An example of my SQL:
Select Attribute1, Stage1Value, Stage2Value, Stage3Value
From attribute, stage
where attribute = project1
So I can't just pull the "Value" column as it needs to know which stage in the query.
There are 30 columns I am trying to pull - of which 13 fall into this category. Thanks for any help you can provide.
So, you want conditional aggregation something :
select a.<col>,
sum(case when s.Condition = 'Stage1' then s.value else 0 end),
. . .
sum(case when s.Condition = 'Stage4' then s.value else 0 end)
from attribute a inner join
stage s
on s.<col> = a.<col>
group by a.<col>

select sum(a), sum(b where c=1) from db; sql conditions in select statement

i guess i just lack the keywords to search, but this is burning on my mind:
how can i add a condition to the sum-function in the select-statement like
select sum(a), sum(b where c=1) from db;?
this means, i want to see the sum of column a and the sum of column b, but only of the records in column b of which column c has the value 1.
the output of heidi just says "bad syntac near WHERE". may there be any other way?
thanks in advance and best regards from Berlin, joachim
The exact syntax may differ depending on the database engine, however it will be along the lines of
SELECT
sum(a),
sum(CASE WHEN c = 1 THEN b ELSE 0 END)
FROM
db
select sum(case when c=1 then b else 0 end)
This technique is useful when you need a lot of aggregates on the same set of data - you can query the entire table without applying a where filter, and have a bunch of these which give you aggregated data for a specific filter.
It's also useful when you need a lot of counts based on filters - you can do sums of 1 or 0:
select sum(case when {somecondition} then 1 else 0 end)

BigQuery SQL same column multiple expressions

I'm using Google's Big Query service to do some data processing...my database looks like:
value
-----
'a'
'b'
'a'
'a'
'a'
'b'
I want to write a query to count the occurrences of the various values.
Example:
Count('a') Count('b')
---------- ----------
4 3
I'd normally use Case to solve this; but BQ doesn't support Case.
Anyone have any ideas?
Thanks!
The first thing I would suggest is a group by:
select value, count(*)
from t
group by value
But you seem to want the values in one row. According to this documentation, it does support case. If you prefer, you can use if:
select sum(if(value = 'A', 1, 0)) as A, sum(if(value = 'B', 1, 0)) as B
from t

How to transform vertical data into horizontal data with SQL?

I have a table "Item" with a number of related items, like so:
ID Rel_ID Name RelRank
--- ------ ---- -------
1 1 foo 1
2 1 bar 2
3 1 zam 3
4 2 foo2 1
I'm trying to get a query so items with the same Rel_ID would appear in the same row, like so:
Rel_ID Name1 Name2 Name3
------ ----- ----- -----
1 foo bar zam
2 foo2
I've tried selecting the table multiple times:
SELECT k.Rel_ID, k.name 'Name1', k2.name 'Name2'
FROM item k, item k2
WHERE k.Rel_ID = k2.Rel_ID
But this fails. Surely there's a transformation or query that could drastically simplify the process, and I'm just missing it because I haven't used SQL in this way before. What am I missing?
[Edit: added RelRank column, which does appear in my data]
Regardless of the database you are using, the concept of what you are trying to achieve is called "Pivot Table".
Here's an example for mysql:
http://en.wikibooks.org/wiki/MySQL/Pivot_table
Some databases have builtin features for that, see the links below.
SQLServer:
http://msdn.microsoft.com/de-de/library/ms177410.aspx
Oracle:
http://www.dba-oracle.com/t_pivot_examples.htm
You can always create a pivot by hand. Just select all the aggregations in a result set and then select from that result set. Note, in your case, you can put all the names into one column using concat (i think that's group_concat in mysql), since you cannot know how many names are related to a a rel_id.
pseudo-select for your case (i don't know mysql):
select rel_id, group_concat(name) from item group by rel_id
I think you are looking for a mysql specific answer.
Keep in mind that the syntax could vary across different data stores.
MySQL has a feature that makes this easy.
SELECT Rel_ID, GROUP_CONCAT(Name SEPARATOR ' ') As Names FROM Item GROUP BY Rel_ID;
that should work :-)
if the names that you listed are static,my below query that i runned sucessfully in sqlfiddle will work
SELECT rel_id,
MAX (DECODE (rel_id, '1', DECODE (relrank, '1', name) , '2',DECODE (relrank, '1', name))) NAME1,
MAX (DECODE (rel_id, '1', DECODE (relrank, '2', name))) NAME2,
MAX (DECODE (rel_id, '1', DECODE (relrank, '3', name))) NAME3
FROM supportContacts
GROUP BY rel_id
heres the SQL fiddle
http://sqlfiddle.com/#!4/480e2/11