sqlite - how to combine overall count and group by? - sql

I have the following table of PHOTOS, their times and months:
TIME|MONTH|PHOTO
----|-----|-----
x1 | mx1 | p1
x2 | mx2 | p2
...
I'd like to get all months sorted descendent BUT, with the total photos count up until that month - not just the count of that month's group.
For example, the following query isn't good enough as it returns the count of each specific month's group instead of the total count up until that group:
select MONTH, count(TIME) from PHOTOS group by MONTH sort by MONTH desc
Ideas?

SQLite has less functionalities compared to other RDBMS but I think this is how you should do it:
SELECT photosA.month,
(SELECT COUNT(time) AS PhotoCounter
FROM photos AS photosB
WHERE photosB.month <= photosA.month) AS total_photos
FROM photos AS photosA
GROUP BY photosA.month
ciao!

select a.month, count(b.month) as CountSmaller
from [PHOTOS] a
inner join [PHOTOS] b on b.[MONTH] <= a.[MONTH]
group by a.time, a.month, a.photo
order by 2 desc
tested in sqlfiddle

Fiddle http://sqlfiddle.com/#!7/812ac/2/0
To solve your problem, firstly you need some kind of month order. You can do it by this query:
select 1 id, 'mx1' m
union
select 2, 'mx2'
union
select 3, 'mx3'
union
select 4, 'mx4'
You can do it in every query by nested query or create separate table.
And manipulating nested queries, aggregate function and joins you can achieve your goal by:
select m2,
(
select count(*) from photos p
inner join
(
select 1 id, 'mx1' month
union
select 2, 'mx2'
union
select 3, 'mx3'
union
select 4, 'mx4'
) m
on p.month = m.month and m.id <= M.id2
)
from
(
select 1 id2, 'mx1' m2
union
select 2, 'mx2'
union
select 3, 'mx3'
union
select 4, 'mx4'
) M
If you have any questions I can answer them in comments.

Related

oracle count query with union

I have a query with union all functionality each giving me count(*) return from respective queries and another count query like below. I want an outer query that gives the total.
1st query
select count(*) from a
union all
select count(*) from b;
Sample result for 1st query:
COUNT
10
40
2nd query
select count(*) from xy;
Sample result for 2nd query:
COUNT
20
I want output like this in 2 rows:
TABLES
COUNT
xy
20
ab
50
something like above. How can I achieve this in oracle? please suggest the best way to do this.
I wrote a select and union all but not sure how to proceed further.
One option is to sum counts returned by the 1st query and then union it with the 2nd; also, add constants which show the source:
select 'ab' what, (select count(*) from a) + (select count(*) from b) cnt from dual
union all
select 'xy', count(*) from xy;
You can use:
SELECT 'ab' AS type,
COUNT(*) AS total
FROM ( SELECT 1 FROM a UNION ALL
SELECT 1 from b );
UNION ALL
SELECT 'xy', COUNT(*)
FROM xy;
You can sum counts from your three unioned Select statements and group the result by combination of sources:
WITH
a AS
( Select LEVEL "A_ID", 'some column a' "COL_A" From Dual Connect By LEVEL <= 30 ),
b AS
( Select LEVEL "B_ID", 'some column b' "COL_B" From Dual Connect By LEVEL <= 20 ),
xy AS
( Select LEVEL "XY_ID", 'some column xy' "COL_XY" From Dual Connect By LEVEL <= 20 )
with above sample data it is like here:
SELECT
CASE WHEN SOURCE IN('a', 'b') THEN 'ab' ELSE SOURCE END "SOURCE",
Sum(CNT) "CNT"
FROM
( Select 'a' "SOURCE", Count(*) "CNT" From a Union All
Select 'b', Count(*) From b Union All
Select 'xy', Count(*) From xy
)
GROUP BY
CASE WHEN SOURCE IN('a', 'b') THEN 'ab' ELSE SOURCE END
--
-- R e s u l t :
-- SOURCE CNT
-- ------ ----------
-- ab 50
-- xy 20
Assuming that your real queries can be a lot more complex, I take it as a given that we shall not try to change them and somehow merge or split them.
Your first query returns two rows. You want to get their sum, so you must aggregate the result and use SUM.
Below query uses CTEs (subqueries in the WITH clause) for your two queries, and then a query that gets this sum. It then uses these CTEs for the final UNION ALL query.
with query1 (cnt) as (select count(*) from a union all select count(*) from b)
, query2 (cnt) as (select count(*) from xy)
, sumquery1 (total) as (select sum(cnt) from query1)
select 'ab' as tables, total from sumquery1
union all
select 'xy' as tables, cnt from query2
order by tables desc;

Google big query count

I am trying to pull all the customers having less than 4 orders
in past 3 months in Google BigQuery.
SELECT a.user_id, b.refer_by, FROM water_db.tb_order a INNER JOIN
water_auth.tb_users b ON a.user_id = b.user_id WHERE ( SELECT
user_id FROM
water_db.tb_order GROUP BY
user_id HAVING
COUNT(DISTINCT(a.user_id <= 4))) AND status = 3 AND DATE(a.order_date) >=
'2017-02-15' AND DATE(a.order_date) <= '2017-05-15';------
I'm guessing that each time a record is added to the table it equates to an order but something like:
SELECT
a.userid, b.refer_by
FROM water_db.tb_order a
INNER JOIN water_auth.tb_users b ON a.user_id = b.user_id
WHERE
(COUNT(userid) < 4)
and
DATE_ADD(MONTH, -4, a.order_date)
The date function may differ as I'm not 100% sure what it is in Google Big Query
I think the best way to approach this is by selecting from the users table, so you don't need to deduplicate IDs, and just expressing the condition as part of your WHERE clause. This should help get you started:
#standardSQL
SELECT
user_id,
refer_by
FROM water_db.tb_users
WHERE (
SELECT COUNT(*)
FROM water_db.tb_order
WHERE tb_users.user_id = tb_order.user_id AND
status = 3 AND
DATE(order_date) BETWEEN '2017-02-15' AND '2017-05-15'
) <= 4;
In this query, the join is expressed as a correlated subquery involving the two tables. You can try it out using sample data with this query:
#standardSQL
WITH tb_users AS (
SELECT 1 AS user_id, 'foo#bar.com' AS refer_by UNION ALL
SELECT 2, 'a#b.com' UNION ALL
SELECT 3, 'baz#baz.com'
),
tb_order AS (
SELECT 1 AS user_id, TIMESTAMP '2017-04-12' AS order_date, 3 AS status UNION ALL
SELECT 2, TIMESTAMP '2017-05-03', 3 UNION ALL
SELECT 1, TIMESTAMP '2017-03-13', 3 UNION ALL
SELECT 1, TIMESTAMP '2017-02-28', 3 UNION ALL
SELECT 2, TIMESTAMP '2017-05-06', 3 UNION ALL
SELECT 1, TIMESTAMP '2017-05-01', 3 UNION ALL
SELECT 1, TIMESTAMP '2017-05-02', 3
)
SELECT
user_id,
refer_by
FROM tb_users
WHERE (
SELECT COUNT(*)
FROM tb_order
WHERE tb_users.user_id = tb_order.user_id AND
status = 3 AND
DATE(order_date) BETWEEN
'2017-02-15' AND '2017-05-15'
) <= 4;

SQL SUM function inquiry

I'm having a hard time summing up a column on two tables. The scenario is something like this (refer to the image below)
Table 1 may have a lot of rows per Date. But Table 2 may only consists of two rows of data per Date. What I wanted to do is to sum up all Item/Price (Table1) according to their Date and ADD them with another SUM of Item/Price of Table2. The category of SUM is by Date.
I tried any joins statement (left, right or inner) but it does not produce the result that I am expecting to. My expected result is the Result table. But on my query, it produces a very high value.
Thanks.
Use a UNION clause like this:
WITH t(d, p) AS (
SELECT [Date], Price FROM Table1
UNION ALL
SELECT [Date], Price FROM Table2
)
SELECT d, SUM(p) FROM t GROUP BY d
You can do this with UNION ALL in either a subquery or a cte, cte shown here:
;WITH cte AS (SELECT [Date], Price
FROM Table1
UNION ALL
SELECT [Date], Price
FROM Table2
)
SELECT [Date], SUM(Price) AS Total_Price
FROM cte
GROUP BY [Date]
Demo: SQL Fiddle
Try This,
with cte (C_Date,C_Price)
as
(
SELECT date,SUM(price) FROM table_1
group by date
union
SELECT date,SUM(price) FROM table_2
group by date
)
select c_date,SUM(c_price) from cte
group by C_Date
Try this
Select t.date,P1+P2
from(
Select Date,sum(Price) P1
from table1 t
group by Date
) t
left join
(
Select Date,sum(Price) P2
from table t2
group by date
) t1 on t.date = t1.date
group by date

Get single column each row difference in SQL Server (alternative of LEAD function)

Get single column each row difference in SQL Server.
In my table, ORIGINAL_DATA is my current column and want to generate new EXPECTED_OUTPUT column with show the difference of each row.
like 40-30 = 10 , 30-25 = 5, 25-10 = 15.
SELECT 10 ORIGINAL_DATA,0 EXPECTED_OUTPUT UNION
SELECT 25, 15 UNION
SELECT 30, 5 UNION
SELECT 40, 10
I have used the LEAD function but it is not supported by my current version of SQL Server.
So can you please help me to solve this without LEAD and SELF JOIN?
As my query already taking too much time, here i have mention only sample data only.
Try this
WITH rows AS
(SELECT Column1 ,ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
FROM (
SELECT 10 Column1 UNION
SELECT 25 UNION
SELECT 30 UNION
SELECT 40
)M)
SELECT
--mp.Column1 ,
mc.Column1,
--mc.rn,
--mp.rn,
CAST(mc.Column1 AS float) - CAST(mp.Column1 AS float) EXPECTED_OUTPUT
FROM rows mc
LEFT JOIN rows mp
ON mp.rn = mc.rn - 1;
Try this, change SQL Script as per table structure Partition By A and Order By B
SELECT ORIGINAL_DATA,
ORIGINAL_DATA-LEAD(ORIGINAL_DATA, 1, 0) OVER (PARTITION BY A ORDER BY B DESC) AS EXPECTED_OUTPUT
FROM Table1

SQL Query, Union Order by like a tree

Hello I have a query like
SELECT 4 AS sortf,XX FROM Table GROUP BY Y
UNION
SELECT 1 AS sortf,XX FROM Table GROUP BY Y
UNION
SELECT 2 AS sortf,XX FROM Table GROUP BY Y
UNION
SELECT 3 AS sortf,XX FROM Table GROUP BY Y
ORDER BY 3,2
My problem is that the line 2 and 3 ar not ordered like a tree. I tried some other combinations but it did not work.
if you want to sort your dataset according to numbers put your code and unions into a common table expression and the use ROW_NUMBER() function to generates row number , something like this :
WITH CTE
AS
(
SELECT 4 AS sortf, productid FROM Production.Products
UNION
SELECT 1 AS sortf,productid FROM Production.Products
UNION
SELECT 2 AS sortf,productid FROM Production.Products
UNION
SELECT 3 AS sortf,productid FROM Production.Products
)
SELECT *, ROW_NUMBER() OVER (ORDER BY productid) AS SortOrder
FROM CTE
ORDER BY SortOrder