Custom table query in SQL Server similar to custom table in SPSS? - sql

From the sample data it will compute the average price per name and code including the combinations for all names and all codes.
Currently I'm using the union all for all the combinations which is a tedious way. Is there a simplest way to query that case?
SELECT NAME ,CODE, AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY
NAME ,CODE
UNION ALL
SELECT 'ALL NAMES' ,CODE, AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY
CODE
UNION ALL
SELECT NAME, 'ALL CODES', AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY NAME
UNION ALL
SELECT 'ALL NAMES', 'ALL CODES, AVG(PRICE)
FROM SAMPLE_DATA

You can use GROUPING SETS:
SELECT NAME, CODE, AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY GROUPING SETS ( (NAME, CODE), (NAME), (CODE), () )
Just include all the combinations you want in the list.

Related

SELECT DISTINCT doesn't appear to work with big query

I am filtering to a second created table that have duplicates removed. However I'm finding that DISTINCT seems not be working, and I end up with rows with identical ids. I want to only select one unique ID and throw any remaining ones away, but this is not what is happening. In other-words I do not care about the other column names.
def de_dupe_affiliates(read_table, write_table):
query = """
CREATE OR REPLACE TABLE `{write_table}` AS
SELECT DISTINCT ID, BRAND, TITLE, SHORT_TITLE, PRICE, FROM `{read_table}`
""".format(read_table=read_table,write_table=write_table)
response = client.query(query).result()
I also tried
SELECT DISTINCT(ID), BRAND
But this did the same. Is it possible to do this with a DISTINCT on one column?
Consider below approach
SELECT AS VALUE ANY_VALUE(t) FROM (
SELECT ID, BRAND, TITLE, SHORT_TITLE, PRICE FROM read_table
) t
GROUP BY ID
Your select clause
SELECT DISTINCT ID, BRAND, TITLE, SHORT_TITLE, PRICE FROM `{read_table}`
is equivalent to
SELECT ID, BRAND, TITLE, SHORT_TITLE, PRICE FROM `{read_table}` GROUP BY ID, BRAND, TITLE, SHORT_TITLE, PRICE
meaning any differences within these fields creates new rows in your result.
Your query works only if ID, BRAND, TITLE, SHORT_TITLE, PRICE fields are unique.
If not, you may use window functions like row_number() or rank() to select one row per id.

Union two tables with different column names

code snippet
As you can see from the results table, the union hasn't worked properly as there is more than one row for each make of car e.g. Toyota is listed for NG and KE in row 1 and for SA in row 3. Does anyone know how to join these tables more successfully?
Thank you!
How about making your last query another CTE, then grouping and summing the cnt on the new CTE?
WITH combined AS (
select title FROM autochek_ng
union all
select title FROM autocheck_kenya)
, brands AS (
SELECT LEFT(title, CHARINDEX(' ' , title)) as brand
FROM combined )
, aggregate as (
select brand, count(brand) as cnt
from brands
group by brand
UNION ALL
select make as brand, count(make) as cnt
from south_africa5000
group by make)
select brand, sum(cnt) cnt
from aggregate
group by brand

Grouping repeated fields in BQ

I have the following table where "product" is a repeated field.
How can I group by "id" and merge the repeated field to sum the quantities so the output looks like this.
Trying to find an elegant solution that does not unnest.
Consider below
select id, array(
select as struct sku, sum(quantity) quantity
from t.product
group by sku
) product
from (
select id, array_concat_agg(product) product
from your_table
group by id
) t
if applied to sample data in your question - output is

select max, min values from two tables

I have two tables. Differ in that an archive is a table and the other holds the current record. These are the tables recording sales in the company. In both we have among other fields: id, name, price of sale. I need to select from both tables, the highest and lowest price for a given name. I tried to do with the query:
select name, max (price_of_sale), min (price_of_sale)
from wapzby
union
select name, max (price_of_sale), min (price_of_sale)
from wpzby
order by name
but such an inquiry draws me two records - one of the current table, one table archival. I want to chose a name for the smallest and the largest price immediately from both tables. How do I get this query?
Here's two options (MSSql compliant)
Note: UNION ALL will combine the sets without eliminating duplicates. That's a much simpler behavior than UNION.
SELECT Name, MAX(Price_Of_Sale) as MaxPrice, MIN(Price_Of_Sale) as MinPrice
FROM
(
SELECT Name, Price_Of_Sale
FROM wapzby
UNION ALL
SELECT Name, Price_Of_Sale
FROM wpzby
) as subQuery
GROUP BY Name
ORDER BY Name
This one figures out the max and min from each table before combining the set - it may be more performant to do it this way.
SELECT Name, MAX(MaxPrice) as MaxPrice, MIN(MinPrice) as MinPrice
FROM
(
SELECT Name, MAX(Price_Of_Sale) as MaxPrice, MIN(Price_Of_Sale) as MinPrice
FROM wapzby
GROUP BY Name
UNION ALL
SELECT Name, MAX(Price_Of_Sale) as MaxPrice, MIN(Price_Of_Sale) as MinPrice
FROM wpzby
GROUP BY Name
) as subQuery
GROUP BY Name
ORDER BY Name
In SQL Server you could use a subquery:
SELECT [name],
MAX([price_of_sale]) AS [MAX price_of_sale],
MIN([price_of_sale]) AS [MIN price_of_sale]
FROM (
SELECT [name],
[price_of_sale]
FROM [dbo].[wapzby]
UNION
SELECT [name],
[price_of_sale]
FROM [dbo].[wpzby]
) u
GROUP BY [name]
ORDER BY [name]
Is this more like what you want?
SELECT
a.name,
MAX (a.price_of_sale),
MIN (a.price_of_sale) ,
b.name,
MAX (b.price_of_sale),
MIN (b.price_of_sale)
FROM
wapzby a,
wpzby b
ORDER BY
a.name
It's untested but should return all your records on one row without the need for a union
SELECT MAX(value) FROM tabl1 UNION SELECT MAX(value) FROM tabl2;
SELECT MIN(value) FROM tabl1 UNION SELECT MIN(value) FROM tabl2;
SELECT (SELECT MAX(value) FROM table1 WHERE trn_type='CSL' and till='TILL01') as summ, (SELECT MAX(value) FROM table2WHERE trn_type='CSL' and till='TILL01') as summ_hist

combine SELECTS in ONE VIEW DISPLAY

I need to know of a way to combine multiple SELECT statements in one VIEW? I tried the UNION ALL, but it fails since I am using unique columns to aggregate the GRAND TOTAL.
I am a student this is part of a group project.
I have one table with 4 columns: account, description, short_description, and balance. The COA (chart of accounts) is an excel spreadsheet that is imported.
CREATE VIEW [account_balance_sums]
AS
SELECT SUM(balance) AS total,
SUBSTRING (Account,0,2) AS account_group
FROM COA
GROUP BY account_group
GO
SELECT * FROM [account_balance_sums]
SELECT SUM(total) AS Grand_total
FROM [account_balance_sums]
Assuming that you are trying to create a view that gives account group and total balance with a single extra row for the total across all accounts then this view should help:
CREATE VIEW [account_balance_sums] AS
SELECT SUM(balance) AS total, SUBSTRING (Account,0,2) AS account_group
FROM COA
GROUP BY account_group
UNION ALL
SELECT SUM(balance), 'Grand Total'
FROM account_group
By the way, the sub-string of the first characters of the account name suggests that you have more than one piece of data in a single column. This indicates a data that is not properly normalised, which you should probably address if you want top marks. See wikipedia on normal form
In a UNION'd statement, there must be:
The same number of columns in each SELECT statement
The data types must match at each position in the SELECT statement
Use:
SELECT *
FROM [account_balance_sums]
UNION ALL
SELECT SUM(total),
NULL AS account_group
FROM [account_balance_sums]
UNION ALL should work. basic structure like this
select a,b,c,d
from t1
union all
select a,b,c,e
from t2
so long as d and e are the same data type.
to do the sum, then you wrap this with the aggregation layer - using this structure as an inline view (among other methods)
something like:
select sum( d )
from (
select a,b,c,d
from t1
union all
select a,b,c,e
from t2
)