How to get all rows with using WHERE using SQL - mysql

I am looking for something, which can select all rows in db using WHERE like this:
SELECT * FROM fb_post WHERE fb_page_id = 17 AND YEAR(date) = ALL ORDER BY date
So, In my app, I set date from local variable.
SELECT * FROM fb_post WHERE fb_page_id = 17 AND YEAR(date) = ? ORDER BY date
In some case, I want to select all years, is there any key word for select all? I don't want to write second query like this:
SELECT * FROM fb_post WHERE fb_page_id = 17 ORDER BY date
Thank you for help

If you send parameter null in order to get all, the below code will help you on mysql. For Mssql replace IFNULL with ISNULL and NVL for Oracle.
SELECT * FROM fb_post WHERE fb_page_id = 17 AND YEAR(date) = IFNULL('your param here',YEAR(date))

You can add a boolean that conditions the date check:
SELECT * FROM fb_post
WHERE fb_page_id = 17 AND (NOT checkDate OR YEAR(date) = ALL)
ORDER BY date
If you set checkDate to false, YEAR(date) = ALL will be ignored.

Related

MySQL - join query results vertically

I am trying to create a summary report for to capture daily stats. Basically I need the outcome similar to:
Table_Name Updated_Rows Created_Rows Date
Table 1 10 5 2019-04-23
Table 2 17 55 2019-04-23
Now I can fetch the individual values using basic commands:
select count(*) as created_rows
from accounts
where date(updated_at) = date(now())
and
select count(*) as created_rows
from accounts
where date(created_at) = date(now())
Can also combine the data using the UNINON ALL,
(SELECT table_name FROM information_schema.tables where table_name='accounts')
UNION ALL
(select count(*) as created_rows from accounts where date(created_at) = date(now()))
UNION ALL
(select count(*) as updated_rows from accounts where date(updated_at) = date(now()))
However the output I get is kind of stacked vertically and I wish to retain the labels/column names and would want to add data row by row for all the tables I want to assess.
I am sure there is an easier way but I can't seem the find a way out to get this done. Don't need the final query, just help me with a direction to look towards.
For a single table, you can do the following:
SELECT 'account' AS 'Table_Name'
, SUM(date(updated_at) = date(now())) 'Updated_Rows'
, SUM(date(created_at) = date(now())) 'Created_Rows'
, date(now()) AS 'Date'
FROM accounts
where SUM(date(updated_at) = date(now())) is basically the same as
IF(SUM(date(updated_at) = date(now())), 1, 0)
Then UNION ALL result from other tables with the similar query.
You could try something like the following (untested):
select '#x' as table_name,
(select count(*) FROM #x and date(created_at) = date(now())) as created_rows,
(select count(*) FROM #x and date(updated_at) = date(now())) as updated_rows
As part of a prepared statement (https://dev.mysql.com/doc/refman/5.6/en/sql-syntax-prepared-statements.html) or proc (https://medium.com/#peter.lafferty/mysql-stored-procedures-101-6b4fe230967) or just union to get multiple tables (note that you'd have to change some syntax). I'm not sure how you need to run this, so I'm not sure what exactly you need, what kind of performance you're after, if you're just going to make a script and manually select the tables or if you're trying to run this on all tables, etc.
EDIT: jxc's query is much better than mine!
Is this what you are looking for? If so, make sure to change the table names in the subsequent UNION ALL queries.
SELECT
'accounts' AS TableName,
SUM(DATE(updated_at) = DATE(NOW())) AS updated_rows,
SUM(DATE(created_at) = DATE(NOW())) AS created_rows,
DATE(NOW()) AS `Date`
FROM
accounts
UNION ALL
SELECT
'accounts2' AS TableName,
SUM(DATE(updated_at) = DATE(NOW())) AS updated_rows,
SUM(DATE(created_at) = DATE(NOW())) AS created_rows,
DATE(NOW()) AS `Date`
FROM
accounts2
and so forth....
EDIT This query is identical to jxc's query posted earlier

How To Get My Teradata Query to Prompt For Dates Between ?YYYYMMDD AND ?YYYYMMDD and

HERE IS THE QUERY:
SELECT
FACDTE.QTR
,FACDTE.WK
,FACDTE."DATE"
,FACDTE.DIV
,FACDTE.DST
,FACDTE.FAC
,FACDTE.DAYS
,COALESCE(OOS.SCN,0) SCN
,RANK() OVER(
PARTITION BY FACDTE.QTR,FACDTE.WK,FACDTE."DATE"
ORDER BY COALESCE (CAST(OOS."OOS COUNT" AS INTEGER),'ns')) AS DIVRANK
,CAST(OOS."OOS COUNT" AS INTEGER) "OOS COUNT"
FROM
(
SELECT
FAC.PARENT_OP_AREA_CD DIV
,FAC.DISTRICT_FINANCE_CD DST
,FAC.STORE_ID FAC
,DTE.QUARTER_ID QTR
,DTE.WEEK_ID WK
,DTE.D_DATE "DATE"
,COUNT(DISTINCT(DTE.D_DATE)) DAYS
FROM LU_STORE_FINANCE FAC
JOIN (
SELECT
DTE_L1.D_DATE
,DTE_L1.WEEK_ID
,DTE_L1.QUARTER_ID
FROM LU_DAY_MERGE DTE_L1
JOIN (SELECT D_DATE FROM LU_DAY_MERGE
WHERE WEEK_ID=(SELECT DISTINCT(WEEK_ID) FROM LU_DAY_MERGE WHERE D_DATE =CURRENT_DATE -2)) DTE_L0 ON DTE_L0.D_DATE =DTE_L1.D_DATE AND DTE_L1.D_DATE < CURRENT_DATE
) DTE
ON DTE.D_DATE BETWEEN FAC.OPENED_DT AND FAC.CLOSED_DT AND
THE CODE IS BELOW I NEED TO PROMPT FOR DATES BETWEEN YYYYMMDD YYYYMMDD INSTEAD of Using the current_DATE... Can I just put in ?YYYYMMDD AND YYYYMMDD in that please?
FAC.PARENT_OP_AREA_CD = '17' AND NOT FAC.STORE_ID IN (4904,3332, 1478,0412,2631,1223) GROUP BY 1,2,3,4,5,6) FACDTE
LEFT JOIN
(SELECT
OOS_L1.STORE_ID FAC
,DTE_L2.WEEK_ID WK
,DTE_L2.D_DATE "DATE"
,AVERAGE(TOT_CT.TOT_OOS) AS "OOS COUNT"
,COUNT(DISTINCT(OOS_L1.SCAN_DT)) SCN
,SUM(CASE WHEN OOS_L1.PRODUCT_SOURCE_CD = 'W' THEN CASE WHEN ITM.DEPARTMENT_ID = 314 THEN OOS_L1.OOS_STR_SCAN_CNT ELSE 0 END ELSE 0 END) AS "DAIRY"
FROM
OOS_STORE_ITEM_DAY OOS_L1
JOIN (SELECT STORE_ID,SCAN_DT ,COUNT(UPC_ID) AS TOT_OOS FROM OOS_ITEM_DETAIL WHERE SCAN_TYP_CD = 'O' GROUP BY 1,2)TOT_CT
ON TOT_CT.STORE_ID = OOS_L1.STORE_ID AND TOT_CT.SCAN_DT=OOS_L1.SCAN_DT AND TOT_CT.TOT_OOS>49
JOIN LU_DAY_MERGE DTE_L2 ON OOS_L1.SCAN_DT=DTE_L2.D_DATE
JOIN LU_UPC ITM ON OOS_L1.UPC_ID = ITM.UPC_ID AND ITM.CORPORATION_ID = 1
GROUP BY 1,2,3) OOS
ON OOS.WK = FACDTE.WK AND OOS.FAC=FACDTE.FAC AND OOS."DATE" = FACDTE."DATE"
ORDER BY 1,2,3,4,5,6
Not saure, what the question is. But if you're talking about the feature in Teradata SQL Assistant to place parameters (with the ?-Syntax):
You can define parameters in SQL Assistant with Keyword ?. Just place ? with the parameter name (no spaces) anywhere in your Editor. SQL Assistant will ask for each parameter and search&replace it before the query is send to the database. The parameters can occur multiple times in the editor, you just have to enter the value once and it will be replaced each occurrence.
SELECT *
FROM myWebOrders
where orderDate >= CURRENT_DATE - ?OrderHistory_Days
UNION ALL
SELECT *
FROM myRetailOrders
where orderDate >= CURRENT_DATE - ?OrderHistory_Days
or
SELECT TOP 50 *
FROM ?myTable

Finding sum conditionally mysql

i have a table test containing columns as:
id
amt
date(yyyy-mm-dd)
and values as
1 10 2017-08-09
1 20 2017-08-10
2 10 2017-09-11
Now i need to sum all the amt for a particular id only if the MONTH(date) = value1 AND YEAR(date) = value2.
I tried the following but am not getting the desired result.
#value1 = 8
#value2 = 2017
#id = 1
SELECT SUM(CASE WHEN MONTH(date) = #value1 AND YEAR(date)= #value2
THEN test.amt
ELSE 0 END) netAmt
FROM test
WHERE id = #id
Desired result should be 30 . However i get 0 .
Any help is appriciated.
this may help you,
select sum(amt) as amt from test where month(date)=8 and year(date)='2017' and id=1;
sql like this:
select sum(amt) from test where date like '2017-08%'
Have you tried the following?
SET #value1 = 8;
SET #value2 = 2017;
SET #id = 1;
select sum(`amt`) as total from test where `id` = #id and MONTH(`date`) = #value1 AND YEAR(`date`)= #value2;
I was working on MySql Workbench and was trying to select three set statements all at a time.
The result was that only the 1st set statement was being set. Executing them separately worked.

Select in Concat mysql

I'm trying to get a date value with:
- Current year
- Current month
- Day number from one select
the query
SELECT rat_data FROM rate_unita WHERE rateid = 1
as a result one INT value.
When I try to execute the following:
SELECT DATE(CONCAT(YEAR(NOW())),(MONTH(NOW())), (SELECT rat_data FROM rate_unita WHERE rateid = 1))
Mysql mark my syntax as incorrect near ' ( MONTH( NOW( ) ) ) , ( SELECT rat_data FROM rate_unita WHERE r
I think that there is something wrong with the way I'm calling the SELECT in the CONCAT, what is the correct query to reach my goal?
Thanks
L
You're closing the concat function too early. Remove some extra parentheis
SELECT DATE(CONCAT(YEAR(NOW()),
MONTH(NOW()),
(SELECT rat_data FROM rate_unita WHERE rateid = 1)
))
But you need to add some hyphens to make it a true date value
SELECT DATE(
CONCAT(
YEAR(NOW()),
'-',
MONTH(NOW()),
'-',
(SELECT rat_data FROM rate_unita WHERE rateid = 1)
)
)
This should result in a date of YEAR-MONTH-rat_data
Here's a working SQL Fiddle
Use DATE_FORMAT function. Here are a few examples:
http://www.w3schools.com/sql/func_date_format.asp
http://www.mysqltutorial.org/mysql-date_format/

Limit rows of every month?

I need to get data between Decemember 2012 to November 2014.
Each month I only need 1500 rows.
For example:
SELECT * FROM data WHERE YEAR(submit_date) = 2012 AND MONTH(submit_date) = 12 limit 1500;
SELECT * FROM data WHERE YEAR(submit_date) = 2013 AND MONTH(submit_date) = 1 limit 1500;
SELECT * FROM data WHERE YEAR(submit_date) = 2013 AND MONTH(submit_date) = 2 limit 1500;
SELECT * FROM data WHERE YEAR(submit_date) = 2013 AND MONTH(submit_date) = 3 limit 1500;
and until Nov 2014
Is there a way to write SQL query smaller?
There are some options list here: http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
IMHO one of the best is using a row-counter:
set #num := 0, #type := '';
select id, name, submit_date,
#num := if(#type = CONCAT(YEAR(submit_date), MONTH(submit_date)), #num + 1, 1) as row_number,
#type := CONCAT(YEAR(submit_date), MONTH(submit_date)) as dummy
from data force index(IX_submit_date)
group by id, name, submit_date
having row_number <= 2;
You can test it here: http://sqlfiddle.com/#!2/e829c/13 (I do a cut for 2 elements, not for 1500)
I think you're looking for a GROUP BY clause. I would need to know a bit more to give you a definitive answer. But the following pseduo-query might guide you in the right direction.
SELECT *, SUM(some_field)
FROM data
GROUP BY MONTH(submit_date)
Or if you only need 1500 rows, select the top 1500 ordered by the date
SELECT TOP(1500) *
FROM data
WHERE submit_date > '12-01-2012' AND submit_date < '11-01-2014'
ORDER BY MONTH(submit_date)
With MySQL you can use LIMIT
SELECT *
FROM data
WHERE submit_date > '12-01-2012' AND submit_date < '11-01-2014'
ORDER BY MONTH(submit_date)
LIMIT 0,1500;
You can do it almost like you have it, just add a UNION between your queries. But you still have to create 1 query per month.
Otherwise you need to enumerate the rows that are returned. You need to first order and enumerate your records, then you can do a select on that select to get only the top X. Not sure if you want to include the last month or not.
SET #prev_date='';
SELECT * FROM (
SELECT IF(#prev_date=submit_date, #incr := #incr+1, #incr:=1) AS row_num,
data.*,
(#prev_date := submit_date) AS set_prev_date
FROM data WHERE submit_date BETWEEN "2012-12-01" AND "2014-11-30"
ORDER BY submit_date
) tmp WHERE row_num<1500;