Populate field in SQL with zero - sql

I have a SQL query which provides brand name and count of order(Case-1).
I have to prepare an hourly report with this but , if I don't have count for one hour for any brand the specific brand will not be displayed(Case-2).
In this case how I can automatically populate brand2 with zero in the alert mail ?
Sample SQL
SELECT distinct(brand), count(*) Hourly Count
FROM table_name where date_time between systimestamp-1/24 and systimestamp
GROUP BY brand;

First, using select distinct with group by is almost never needed (certainly not in this case where one column is needlessly surrounded by parentheses) and shows a lack of understanding of both constructs.
One method to do what you want is to use conditional aggregation:
SELECT brand,
SUM(CASE WHEN date_time between systimestamp-1/24 and systimestamp THEN 1 ELSE 0 END) as HourlyCount
FROM table_name
GROUP BY brand;
Another method assumes you have a table with all the brands:
SELECT b.brand, count(t.brand) as HourlyCount
FROM brands b LEFT JOIN
table_name
ON b.brand = t.brand AND
t.date_time between systimestamp-1/24 and systimestamp
GROUP BY b.brand;

Pls find below what I was looking for.
SELECT DISTINCT(BRAND_NAME),SUM(COUNT)FROM(
SELECT distinct(BRAND_NAME) ,count(*) COUNT
FROM TABLE
UNION ALL
SELECT BRAND_NAME,0 AS COUNT
FROM (SELECT 'Brand1' AS BRAND_NAME FROM DUAL
UNION ALL
SELECT 'Brand2' AS BRAND_NAME FROM DUAL
UNION ALL
SELECT 'Brand3' AS BRAND_NAME FROM DUAL)
TEMP1)
TEMP2
GROUP BY BRAND_NAME
ORDER BY 1;

Related

select max from a count in sql

I have :
SELECT
"Month",
COUNT( Trip_Id ) AS 'Number of Trips'
FROM
Tor_Bikes AS tb
GROUP BY
"Month";
Which gives me a table of each month with its number of trips for that month. I need the month that has the most number of trips. How do I do this?
WARNING: UNTESTED
I'm learning SQL myself, so this is by no means canonical, and there may be mistakes. We all know how to produce such a table:
(SELECT `productID`, count(`productID`) AS `TotalPriceChanges` FROM `ProductCostHistory` GROUP BY `productID`)
ProductID Count(*)
'707' | '3'
'708' | '3'
'709' | '1'
'710' | '1'
'711' | '3'
If I'm understanding correctly, you want to select the Max value of THIS table. Well, you can simply use the above as a derived table - sub query or CTE (Common Table Expression). Using MYSQL it would be something like this:
Select ProductID, max(TotalPriceChanges) FROM
(SELECT `productID`, count(`productID`) AS `TotalPriceChanges` FROM `ProductCostHistory` GROUP BY `productID`) as derivedTable
Group by `ProductID`
We use an alias as to name the derived table, and instead of using the aggregative function count we use the function max. The above works for me.
Final Solution
SELECT Month, Max('Number of Trips') FROM
(
SELECT
"Month",
COUNT( Trip_Id ) AS 'Number of Trips'
FROM
Tor_Bikes AS tb
GROUP BY
"Month" AS DerivedTable;
)
GROUP BY MONTH
You should use subqueries to achieve that:
SELECT MAX(Number_of_Trips) FROM (SELECT "Month", Count( Trip_Id ) FROM
Tor_Bikes AS tb
GROUP BY
"Month";)
Here is the query you are searching for:
SELECT Month, Max('Number of Trips')
FROM
(
SELECT Month, COUNT( Trip_Id ) AS 'Number of Trips'
FROM Trips AS tb
GROUP BY Month
)
Using ORDER BY count() :
SELECT
Month,
count(Trip_Id) AS amount
FROM
Tor_Bikes
GROUP BY
Month
ORDER BY
amount DESC
LIMIT
1
;

How to write SQL query without join?

Recently during an interview I was asked a question: if I have a table like as below:
The requirement is: how many orders and how many shipments per day (based on date column) - output needs to be like this:
I have written the following code, but interviewer ask me to write a SQL query without JOIN and UNION, achieve the same output.
SELECT
COALESCE(a.order_date, b.ship_date), orders, shipments
FROM
(SELECT
order_date, COUNT(1) AS orders
FROM
table
GROUP BY 1) a
FULL JOIN
(SELECT
ship_date, COUNT(1) AS shipments
FROM table) b ON a.order_date = b.ship_date
Is this possible? Could you guys please advice?
You can use UNION and GROUP BY with conditional aggregation as follows:
SELECT DATE_,
COUNT(CASE WHEN FLAG = 'ORDER' THEN 1 END) AS ORDERS,
COUNT(CASE WHEN FLAG = 'SHIP' THEN 1 END) AS SHIPMENTS
FROM (SELECT ORDER_DATE AS DATE_, 'ORDER' AS FLAG FROM YOUR_TABLE
UNION ALL
SELECT SHIP_DATE AS DATE_, 'SHIP' AS FLAG FROM YOUR_TABLE) T
In BigQuery, I would express this as:
select date, countif(n = 0) as orders, countif(n = 1) as numships
from t cross join
unnest(array[order_date, ship_date]) date with offset n
group by 1
order by date;
The advantage of this approach (over union all) is two-fold. First, it only scans the table once. More importantly, the unnest() is all on the same node where the data resides -- so data does not need to be moved for the unpivot.

How to retrieve information from table in one statement when the result has different numbers of rows?

I want to retrieve different information in one statement from the same table and they have different number of rows.
The first select has five rows in the result and the second select has three rows because some prices have null value. I thought maybe if I can put zero instead of null so they will match the same number of rows but I don't know how to do that, or is there another solution?
select count(ID), Land
from Film_ha2911
group by Land
union
select count(ID)
from Film_ha2911
where Price is not null
group by Land;
The use of UNION implies that the number and type of columns in select must corresponding
so in your case you should use null for not select columns
select count(ID), Land
from Film_ha2911
group by Land
union
select count(ID), null
from Film_ha2911
where Price is not null
group by Land;
But in this case seems you need a left join on the subquery for land
select t1.count1, t1.land , t2.count2
from (
select count(ID) count1, Land
from Film_ha2911
group by Land
) t1
left join (
select count(ID) count2, land
from Film_ha2911
where Price is not null
group by Land;
) t2 on t1.land = t2.land
The desired result can be achieved by single SELECT without UNION.
Extra column: PriceNotNull to differentiate is Price value filled or not:
SELECT
Land,
CASE WHEN Price IS NOT NULL THEN 'True' ELSE 'False' END PriceNotNull,
COUNT(ID) AS Count_ID
FROM Film_ha2911
GROUP BY Land, CASE WHEN Price IS NOT NULL THEN 'True' ELSE 'False' END
You can just use count():
select Land, count(*) as total_rows,
count(price) as total_with_price
from Film_ha2911
group by Land;
count() counts the number of non-NULL values, so no special logic is needed to count non-NULL values. By count(id) I assume you want to count all the rows. count(*) is more explicit -- as would count(1) which some people prefer.
If you actually want this on separate rows, I would add an indicator for what the count means:
select Land, 'total rows' as which, count(*) as total_rows
from Film_ha2911
group by Land
union all
select Land, 'with price', count(price)
from Film_ha2911
group by Land;
However, I think the first version with two separate columns is more useful.

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

How to put the Order BY in SQL UNION so TOTALS will show up always as last row?

I have SQL UNION where second part of that statement is the row that represents TOTALS. How can I ORDER BY where TOTALS will ALWAYS will show up as the last row?
Add an extra column to the queries being UNIONed, and make that column the first column in your ORDER BY clause.
So if I started with something like this:
SELECT product, price
FROM table
UNION
SELECT 'Total' AS product, SUM(price)
FROM table
I'd add a new column like this:
SELECT product, price
FROM (
SELECT product, price, 0 AS union_order
FROM table
UNION
SELECT 'Total' AS product, SUM(price), 1 AS union_order
FROM table
)
ORDER BY union_order
That way, regular products appear first, then the total appears at the end.
Have you tried using GROUP BY ROLLUP - it might be just want you want, although it's difficult to tell when you haven't posted your query.
You could try adding an 'order' column to each query and then order by that column...
SELECT x.*
FROM
(
SELECT columns, 2 AS [Order]
UNION
SELECT totals, 1 AS [Order]
) x
ORDER BY x.[Order]
select * from
(
select 1 as prio
, col1
, col2
...
from tableA
union
select 2 as prio
, totalCol1
, totalCol2
...
from tableB
) order by prio