Beginner's question here... I have a table of tree measurements being 3 fields: - ID, Diameter_1, Diameter_2
& I wish to get to these 3 fields: - ID, DiameterName, DiameterMeasurement
Input and Desired Output
SELECT DISTINCT ID, Diameter_1
FROM tblDiameters
UNION SELECT DISTINCT ID, Diameter_2
FROM tblDiameters;
Though it results in only 2 fields. How may the field: - DiameterMeasurement be brought in?
Many thanks :-)
You were on the right track to use a union. Here is one viable approach:
SELECT ID, 'Diameter_1' AS DiameterName, Diameter_1 AS DiameterMeasurement
FROM tblDiameters
UNION ALL
SELECT ID, 'Diameter_2', Diameter_2
FROM tblDiameters
ORDER BY ID, DiameterName;
Related
Plain and simple: Is it possible to create a dynamic ordering by system, depending on the value inside the column, the query will query.
The query goes something like this:
SELECT id, name, sortbycolumn FROM table
WHERE id = :in_id
UNION
SELECT id, name, null sortbycolumn FROM table
WHERE id = :in_id
ORDER BY -- This part I simply don't know how to write. I have tried case and decode...
To answer. I did finally find the solution. It was quite simple and whilst I read through other answers, I was confused as to why it did not work for me. Apparently the index of a column will not work when using case when.
In the end, I put up the whole query with unions into a subquery with the solution being:
SELECT * FROM(
SELECT id, name, sortbycolumn FROM table
WHERE id = :in_id
UNION
SELECT id, name, null sortbycolumn FROM table
WHERE id = :in_id
)
ORDER BY
case when sortbycolumn = 1 THEN id,
case when sortbycolumn = 2 then name
else id end
I have a table with three columns with an ID, a therapeutic class, and then a generic name. A therapeutic class can be mapped to multiple generic names.
ID therapeutic_class generic_name
1 YG4 insulin
1 CJ6 maleate
1 MG9 glargine
2 C4C diaoxy
2 KR3 supplies
3 YG4 insuilin
3 CJ6 maleate
3 MG9 glargine
I need to first look at the individual combinations of therapeutic class and generic name and then want to count how many patients have the same combination. I want my output to have three columns: one being the combo of generic names, the combo of therapeutic classes and the count of the number of patients with the combination like this:
Count Combination_generic combination_therapeutic
2 insulin, maleate, glargine YG4, CJ6, MG9
1 supplies, diaoxy C4C, KR3
One way to match patients by the sets of pairs (therapeutic_class, generic_name) is to create the comma-separated strings in your desired output, and to group by them and count. To do this right, you need a way to identify the pairs. See my Comment under the original question and my Comments to Gordon's Answer to understand some of the issues.
I do this identification in some preliminary work in the solution below. As I mentioned in my Comment, it would be better if the pairs and unique ID's existed already in your data model; I create them on the fly.
Important note: This assumes the comma-separated lists don't become too long. If you exceed 4000 characters (or approx. 32000 characters in Oracle 12, with certain options turned on), you CAN aggregate the strings into CLOBs, but you CAN'T GROUP BY CLOBs (in general, not just in this case), so this approach will fail. A more robust approach is to match the sets of pairs, not some aggregation of them. The solution is more complicated, I will not cover it unless it is needed in your problem.
with
-- Begin simulated data (not part of the solution)
test_data ( id, therapeutic_class, generic_name ) as (
select 1, 'GY6', 'insulin' from dual union all
select 1, 'MH4', 'maleate' from dual union all
select 1, 'KJ*', 'glargine' from dual union all
select 2, 'GY6', 'supplies' from dual union all
select 2, 'C4C', 'diaoxy' from dual union all
select 3, 'GY6', 'insulin' from dual union all
select 3, 'MH4', 'maleate' from dual union all
select 3, 'KJ*', 'glargine' from dual
),
-- End of simulated data (for testing purposes only).
-- SQL query solution continues BELOW THIS LINE
valid_pairs ( pair_id, therapeutic_class, generic_name ) as (
select rownum, therapeutic_class, generic_name
from (
select distinct therapeutic_class, generic_name
from test_data
)
),
first_agg ( id, tc_list, gn_list ) as (
select t.id,
listagg(p.therapeutic_class, ',') within group (order by p.pair_id),
listagg(p.generic_name , ',') within group (order by p.pair_id)
from test_data t join valid_pairs p
on t.therapeutic_class = p.therapeutic_class
and t.generic_name = p.generic_name
group by t.id
)
select count(*) as cnt, tc_list, gn_list
from first_agg
group by tc_list, gn_list
;
Output:
CNT TC_LIST GN_LIST
--- ------------------ ------------------------------
1 GY6,C4C supplies,diaoxy
2 GY6,KJ*,MH4 insulin,glargine,maleate
You are looking for listagg() and then another aggregation. I think:
select therapeutics, generics, count(*)
from (select id, listagg(therapeutic_class, ', ') within group (order by therapeutic_class) as therapeutics,
listagg(generic_name, ', ') within group (order by generic_name) as generics
from t
group by id
) t
group by therapeutics, generics;
I have the following genomic table (over 12K rows) in BigQuery. A long list of the PIK3CA_features (column 2) are related to the same sample_id (column 1)
Row sample_id PIK3CA_features
1 hu011C57 chr3_3930069__TGT
2 hu011C57 chr3_3929921_TC
3 hu011C57 chr3_3929739_TC
4 hu011C57 chr3_3929813__T
5 hu011C57 chr3_3929897_GA
6 hu011C57 chr3_3929977_TC
7 hu011C57 chr3_3929783_TC
I would like to generate the following table:
Row sample_id chr3_3930069__TGT chr3_3929921_TC chr3_3929739_TC
1 hu011C57 1 1 0
2 hu011C58 0
Meaning, one row for every sample ID and a 1/0 if the PIK3CA_feature exist at this sample.
Any idea how to easily generate this table?
Many thanks for any idea!
The only idea that comes to mind is using the concepts of ARRAYS and STRUCTS to get somewhat close to what you need, like so:
WITH data AS(
SELECT 'hu011C57' sample_id, 'chr3_3930069__TGT' PIK3CA_features union all
SELECT 'hu011C57', 'chr3_3929921_TC' union all
SELECT 'hu011C57', 'chr3_3929739_TC' union all
SELECT 'hu011C57', 'chr3_3929813__T' union all
SELECT 'hu011C57', 'chr3_3929897_GA' union all
SELECT 'hu011C57', 'chr3_3929977_TC' union all
SELECT 'hu011C57', 'chr3_3929783_TC' union all
SELECT 'hu011C58', 'chr3_3929783_TC' union all
SELECT 'hu011C58', 'chr3_3929921_TC'
),
all_features AS (
SELECT DISTINCT PIK3CA_features FROM data
),
aggregated_samples AS(
SELECT
sample_id,
ARRAY_AGG(DISTINCT PIK3CA_features) features
FROM data
GROUP BY sample_id
)
SELECT
sample_id,
ARRAY(SELECT AS STRUCT PIK3CA_features, PIK3CA_features IN (SELECT feature FROM UNNEST(features) feature) FROM all_features AS present ORDER BY PIK3CA_features) features
FROM aggregated_samples
This will return for you one row per sample_id and a correspondent array of structs with each feature and its presence in the sample_id.
As BigQuery natively supports this type of data structure maybe you could have this representation for your data without losing any capacity for advanced analyzes such as using analytical functions, subqueries and so on.
You can accomplish this by grouping on the sample id.
SELECT
sample_id,
COUNTIF(PIK3CA_features = 'chr3_3930069__TGT') as chr3_3930069__TGT,
COUNTIF(PIK3CA_features = 'chr3_3929921_TC') as chr3_3929921_TC,
COUNTIF(PIK3CA_features = 'chr3_3929739_TC') as chr3_3929739_TC
FROM [your_table]
GROUP BY sample_id;
Assuming you have no duplicate PIK3CA_features per sample id, this should give you what you need.
I'm new to the community but have referenced it many times in the past. I have an issue I'm trying to overcome in Access, specifically with a SORT BY issue in SQL.
Long story short, I need to create a report based on the results of several different queries. I used a Union query to skirt the "Query is too complex" issue. The results of the query aren't in the order I'd like them, though.
Since this UNION query is not based on one specific table, rather the results of many queries, I'm not able to sort by a specific column header.
I want to sort the results by the way they are written in the SQL statement. Can anyone provide some insight to how to do this? I've attempted several different ways but always end up with an error message. Here's the code, and any help is greatly appreciated.
SELECT [Aqua-Anvil_Total].Expr1
FROM [Aqua-Anvil_Total];
UNION SELECT [Aqua-Reslin_Total].Expr1
FROM [Aqua-Reslin_Total];
UNION SELECT [Aqua_Zenivex_Total].Expr1
FROM [Aqua_Zenivex_Total];
UNION SELECT [Aqualuer_20-20_Total].Expr1
FROM [Aqualuer_20-20_Total];
UNION SELECT [Avalon_Total].Expr1
FROM [Avalon_Total];
UNION SELECT [BVA_13_Total].Expr1
FROM [BVA_13_Total];
UNION SELECT [Deltagard_Total].Expr1
FROM [Deltagard_Total];
UNION SELECT [Envion_Total].Expr1
FROM [Envion_Total];
UNION SELECT [Scourge_18-54_Total].Expr1
FROM [Scourge_18-54_Total];
UNION SELECT [Zenivex_E20_Total].Expr1
FROM [Zenivex_E20_Total];
This uses union all instead of union, so if you are using union to remove duplicates, there would be more work to do after this.
select Expr1
from (
select [Aqua-Anvil_Total].Expr1, 0 as sort
from [Aqua-Anvil_Total]
union all select [Aqua-Reslin_Total].Expr1, 1 as sort
from [Aqua-Reslin_Total]
union all select [Aqua_Zenivex_Total].Expr1, 2 as sort
from [Aqua_Zenivex_Total]
union all select [Aqualuer_20-20_Total].Expr1, 3 as sort
from [Aqualuer_20-20_Total]
union all select [Avalon_Total].Expr1, 4 as sort
from [Avalon_Total]
union all select [bva_13_Total].Expr1, 5 as sort
from [bva_13_Total]
union all select [Deltagard_Total].Expr1, 6 as sort
from [Deltagard_Total]
union all select [Envion_Total].Expr1, 7 as sort
from [Envion_Total]
union all select [Scourge_18-54_Total].Expr1, 8 as sort
from [Scourge_18-54_Total]
union all select [Zenivex_E20_Total].Expr1, 9 as sort
from [Zenivex_E20_Total]
) as u
order by u.sort
I have these four separate queries that I would like to consolidate into one result set and I'm not quite sure how to do it. Basically, I would like to see a single output with the following columns:
name - items_created - items_modified - copies_created - copies_modified
select t02CreatedBy as name, count(t02CreatedBy) as items_created
from dbo.Items_t02
where t02DateCreated > getdate() - 7
group by t02CreatedBy
select t02ModifiedBy as name, count(t02ModifiedBy) as items_modified
from dbo.Items_t02
where t02DateModified > getdate() - 7
group by t02ModifiedBy
select t03CreatedBy as name, count(t03CreatedBy) as copies_created
from dbo.Copies_t03
where t03DateCreated > getdate() - 7
group by t03CreatedBy
select t03ModifiedBy as name, count(t03ModifiedBy) as copies_modified
from dbo.Copies_t03
where t03DateModified > getdate() - 7
group by t03ModifiedBy
The tricky part for me is understanding how to combine these while still keeping the various groupings. I need to make sure that t02DateCreated is tied to t02CreatedBy and t02DateModifed is tied to t02ModifiedBy (etc...). Not sure how to do this in one query.
Any suggestions? Or am I going about this the wrong way?
Change the select statement to include something like this
select **'Query 1' as Type**, t03ModifiedBy as name, count(t03ModifiedBy) as copies_modified
from dbo.Copies_t03
where t03DateModified > getdate() - 7
group by t03ModifiedBy
and then add a 'Union All' between each query.
Well, this is a way you could still do it in SQL-server (I haven't tested it though):
SELECT name,
(select count(t02CreatedBy) from dbo.Items_t02
where t02DateCreated>getdate()-7 and t02CreatedBy=name) createdItems
(select count(t02ModifiedBy) from dbo.Items_t02
where t02DateModified>getdate()-7 and t02ModifiedBy=name) modifiedItems
(select count(t03CreatedBy) from dbo.Copies_t03
where t03DateCreated>getdate()-7 and t03CreatedBy=name) createdCopies
(select count(t03ModifiedBy) from dbo.Copies_t03
where t03DateModified>getdate()-7 and t03ModifiedBy=name) modifiedCopies
FROM ( select t02CreatedBy name FROM dbo.Items_t02
union all select t02ModifiedBy FROM dbo.Items_t02
union all select t03CreatedBy FROM dbo.Copies_t03
union all select t03ModifiedBy FROM dbo.Copies_t03 )
allnames GROUP BY name
The outer (grouped) query collects all the possible names, as they might appear in any of the four columns t02CreatedBy,t02ModifiedBy, t03CreatedBy or t03ModifiedBy. It then puts together the counts for each of these columns in the relevant tables by using the four subqueries.
As I don't know your data I used a UNION ALL-construct in the outer query. If you can guarantee for one of those columns (e.g. t02ModifiedBy) to actually contain "all possible" names, then it would also be OK to just use that column alone there, like:
...
FROM t02ModifiedBy FROM dbo.Items_t02 GROUP BY name