mysql between datetime shows wrong record - mysql

I have this query:
SELECT id
, order_date
, seat_number
, cashier_fk
, branch_fk
, waiter_fk
, void
, total_amount
, customer_name
, payment
, notes
, down_payment
, received_date
, void_reason
, discount
, discount_percentage
, printed
, done
, vat
, service_charge
FROM order_tbl
WHERE received_date between "2018-03-15" AND "2018-03-18"
but it shows
My table has this record:
id-------order_date
1-------2018-03-09 09:09:25
2-------2018-03-13 18:29:16
3-------2018-03-13 20:00:49
4-------2018-03-13 20:01:46
5-------2018-03-13 20:05:48
6-------2018-03-13 20:06:34
7-------2018-03-13 20:07:15
9-------2018-03-16 19:06:23
10-------2018-03-16 20:22:26
But it shows only
id-------order_date
5-------2018-03-13 20:05:48
6-------2018-03-13 20:06:34
7-------2018-03-13 20:07:15
9-------2018-03-16 19:06:23
10-------2018-03-16 20:22:26
What is wrong with my query?

Do not use between with dates or date/times. The time component throws everything off.
Instead, express the logic as:
WHERE received_date >= '2018-03-15' AND
received_date < '2018-03-19'
Note the inequality at the end of the range. This ensures that you get everything from that date.
Aaron Bertrand has a really good blog post on the subject, What do BETWEEN and the devil have in common?.

Related

how to give alias to field with custom comments while executing select query in phpmyadmin

SELECT DISTINCT office_nameh
, office_code
, ddo_code
, present_post_ac as ac_code
{here i want to provide my custom comments}
, emp_catg
FROM employee_data
WHERE 1
Suppose I have a table where I have given comments to field/column
now I want to give an alias to a column name and comment
office_nameh |office_code|ddo_code|ac_code |emp_catg
Office Name in Hindi|Office Code|DDO code|my comment|Employee Catg
What's wrong with...
SELECT DISTINCT office_nameh
, office_code
, ddo_code
, present_post_ac ac_code
, 'my comments here' custom_comments
, emp_catg
FROM employee_data
WHERE 1

SSIS Package -Count based on multiple columns

I need to create an SSIS Package that provides me the count of workdoneby (contractor/company).
Input table from sql server db:
I need to count no of orders by contractor and company for a particular day + station + worktype + accountno.
My output should look like this.
Can someone help me how to create a package to get the desired output?
Since the data is in a table, you can ask the database engine to do the calculation logic.
Setup
I created a temporary table and populated it with the supplied data.
CREATE TABLE
#Source
(
[Date] date
, Station char(3)
, worktype char(2)
, Accountno varchar(10)
, workdoneby varchar(10)
)
INSERT INTO
#Source
(
Date
, Station
, worktype
, Accountno
, workdoneby
)
VALUES
('2018-06-24', 'RMS', 'RH', 'I.145.001', 'Company')
, ('2018-06-24', 'RMS', 'PH', 'I.145.001', 'Contractor')
, ('2018-06-24', 'RMS', 'PH', 'I.145.002', 'Company')
, ('2018-06-24', 'RMS', 'PH', 'I.145.002', 'Contractor');
Query time
Now let's query! I find it is helpful to break these problems down into smaller pieces. The first thing I want to do is break out the workdoneby column into two columns with a 1 or 0
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
Running that let's me look at the results and see I still have 4 rows and I get the correct entity counted.
The next step is to collapse/summarize/roll-up the values. You indicate we should group by date/station/worktype/accountno so that's exactly what we're going to to do.
I find it easier to debug if I take that first query and make it a derived table so the basic form now becomes SELECT * FROM (ORIGINAL QUERY HERE) AS D thus
SELECT
D.Date
, D.Station
, D.worktype
, D.Accountno
, D.contractorCount
, D.companyCount
FROM
(
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
) D
Now that you can see it's giving the same original results, we're going to use the SUM function on the contractorCount and companyCount columns and GROUP BY date/station/worktype/accountno
SELECT
D.Date
, D.Station
, D.worktype
, D.Accountno
, SUM(D.contractorCount) AS contractor
, SUM(D.companyCount) AS company
FROM
(
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
) D
GROUP BY
D.Date
, D.Station
, D.worktype
, D.Accountno;
SSIS
Now that we have data looking as expected, within SSIS you need to do something with it. Your question doesn't specify what you need to do but likely you're going to use a Data Flow Task to push this aggregated data from one place to another destination (different server, Excel, etc) or you're going to push this data into a table on the same server in which case you're going to use an Execute SQL Task

Age Calculation duplicate column using sql server 2008 R2

I have login table with DOB Column. I need duplicate column for age. But i can't do this. I can convert DOB column convert to Age for alone
`SELECT FLOOR(DATEDIFF(DAY,'10/10/1990' , getdate()) / 365.25)` works fine.
But I need to convert whole column.
If I'm Using
SELECT FLOOR(DATEDIFF(DAY,Select DOB From login_tbl , getdate()) / 365.25) like this,
It's throwing error. How can I get it?
Thankyou
Your approach will get wrong result in such cases below:
declare #now date
set #now = '11/10/2014'
select
FLOOR(DATEDIFF(DAY,'11/10/2013' , #now) / 365.25) -- should be 1 but will get 0
, FLOOR(DATEDIFF(DAY,'11/10/2012' , #now) / 365.25) -- should be 2 but will get 1
, DATEDIFF(DAY,'11/10/2013' , #now)
, DATEDIFF(DAY,'11/10/2012' , #now)
My suggestion is :
declare #now date
set #now = '11/10/2014'
select (convert(int,convert(varchar(8), #now ,112))
- convert(int,convert(varchar(8),convert(date,'11/10/2013'),112) ) )/10000
You could see my explain in this answer.
So for your login_tbl you could:
select
DOB, (convert(int,convert(varchar(8), DOB ,112))
- convert(int,convert(varchar(8),convert(date,'11/10/2013'),112) ) )/10000 as AGE
from
login_tbl
select trunc((trunc(sysdate) - to_date('16-mar-2010', 'dd-mon-yyyy'))/ (365.23076923074))
from dual

apply an if condition in a sql query

i want to use a if condition in a sql query according to following need.
"if a year field is null then do not calculate age and if it is set then it have to execute.
here is my query.where is the problem?please consider this scenario
'if month and date is there like for example 0000-03-12'
SELECT id, name, birth_date, birth_time,
city_native, country_native, sex,
city_current, country_current, image,
if(YEAR(birth_date)='','',YEAR(CURDATE()) - YEAR(birth_date) -
(RIGHT(CURDATE(),5) < RIGHT(birth_date,5)),'') AS age
FROM birth_user u
WHERE <condition>;
You can use IFNULL() to check birth_date is NULL
CASE WHEN IFNULL(birth_date,0)=0 THEN '' ELSE YEAR(CURDATE()) - YEAR(birth_date) END as age
If your need is "if it is null", why are you comparing it to zero?
if(birth_date is null, 0, YEAR(CURDATE()) - ......) AS age
Where that 0 there is a suitable "default age".
Use NULL instead of 0000
SELECT id, name, birth_date, birth_time,
city_native, country_native, sex,
city_current, country_current, image,
if(birth_date is null,'',YEAR(CURDATE()) - YEAR(birth_date) -
(RIGHT(CURDATE(),5) < RIGHT(birth_date,5)),'') AS age
FROM birth_user u
WHERE " . implode(' AND ', $where);

Getting last months data from the database

My query currently gets yesterdays data but I now want to get all of last months data. (E.g.from 1st to 31st)
$res = mysql_query("SELECT
FROM_UNIXTIME( enquiry_time ), `id` ,
`fullname` , `address1` , `citytown` ,
`postcode` , `telno` ,
`property_value` ,`total_secured_debt`
, `email` , `on_market` , `agent` ,
`reason` , `price_concession` ,
`asking_price` , `form_page` FROM
$table WHERE TO_DAYS(FROM_UNIXTIME( enquiry_time )) = (TO_DAYS(NOW())-1)
");
There is not a TO_MONTHS so im not sure where to start!
Try:
$res = mysql_query("
SELECT FROM_UNIXTIME(`enquiry_time`), `id`, `fullname`, `address1`,
`citytown`, `postcode`, `telno`, `property_value`, `total_secured_debt`,
`email`, `on_market`, `agent`, `reason`, `price_concession`,
`asking_price`, `form_page`
FROM $table
WHERE YEAR(FROM_UNIXTIME(`enquiry_time`)) = YEAR(CURDATE() - INTERVAL 1 MONTH)
AND MONTH(FROM_UNIXTIME(`enquiry_time`)) = MONTH(CURDATE() - INTERVAL 1 MONTH)
");
This would all work vastly better and faster if enquiry_time were a native DATE or DATETIME field, with an index, instead of a Unix timestamp.
Looking for function MONTH?
That will work (like your TO_DAYS does now), but remember you may be paying a hefty performance price if the table is large: MySQL can't use an index when the WHERE condition depends on a function rather than directly on the indexed column (use EXPLAIN to see the query plan and confirm that this is the case). Performance-wise, you're better off computing the lower and upper bound of the times you want to see (with functions and arithmetic on NOW()) and then using a straight BETWEEN in your WHERE. Again, use EXPLAIN to double check -- trying to second guess MySQL's query optimizer is a sterile exercise, it's much easier to check on what it plans to do;-).
Could you use something like the following? I think it will get you what you want.
FROM_UNIXTIME(enquiry_time)
BETWEEN date_format(NOW() - INTERVAL 1 MONTH, '%Y-%m-01')
AND last_day(NOW() - INTERVAL 1 MONTH)
Here's the reference.
While chaos's answer will work, if $table is indexed by enquiry_time,
then it will be faster to compare against that field directly than against a function of it.
That transforms his answer into the even uglier:
$res = mysql_query("
SELECT FROM_UNIXTIME(enquiry_time), id, fullname, address1,
citytown, postcode, telno, property_value, total_secured_debt,
email, on_market, agent, reason, price_concession, asking_price,
form_page
FROM $table
WHERE enquiry_time >= UNIX_TIMESTAMP(concat(year(curdate() - interval 1 month), '-', month(curdate() - interval 1 month), '-01'))
AND enquiry_time < UNIX_TIMESTAMP(concat(year(curdate()), '-', month(curdate()), '-01'))
");
i see you are using php so this might be better than wrestling with mysql functions:
$end_of_month = strtotime(date('Y-m-01 00:00:00'))-1;
$start_of_month = strtotime(date('Y-m-01 00:00:00',$end_of_month));
$res = mysql_query("SELECT
FROM_UNIXTIME( enquiry_time ), `id` ,
`fullname` , `address1` , `citytown` ,
`postcode` , `telno` ,
`property_value` ,`total_secured_debt`
, `email` , `on_market` , `agent` ,
`reason` , `price_concession` ,
`asking_price` , `form_page` FROM'
$table WHERE enquiry_time >= '".$start_of_month."' AND enquiry_time <= '".$end_of_month."'
");