name amount date
x 200 2016-08-11 07:00:00
x 111 2016-08-03 19:32:34
y 10 2016-07-19 07:00:00
y 9 2016-07-20 09:30:00
I want to get last day paid amount for each user,I want an output like this
name amount date
x 200 2016-08-11 07:00:00
y 9 2016-07-20 09:30:00
how to find a user's last updated data group by each users
Simply try this
$sql = "SELECT * FROM table_name ORDER BY `date` DESC GROUP BY `name`";
$query = $this->db->query($sql);
$result = $query->result_array();
print_r($result);
using MAX we can achieve this
DECLARE #Table1 TABLE
( name varchar(1), amount int, date varchar(19))
;
INSERT INTO #Table1
( name , amount , date )
VALUES
('x', 200, '2016-08-11 07:00:00'),
('x', 111, '2016-08-03 19:32:34'),
('y', 10, '2016-07-19 07:00:00'),
('y', 9, '2016-07-20 09:30:00')
;
Script
select T.name , T.amount,TT.Dt as Dates from #Table1 T
INNER JOIN (select name,MAX(date)Dt from #Table1
GROUP BY Name)TT
ON T.name = TT.name AND T.date = TT.Dt
ORDER BY T.name
Related
I've got a following database entry:
id date start_time
1 2015-12-25 08:00:00
2 2015-12-30 08:00:00
3 2015-12-30 09:00:00
Now I just want to select the date of those entries where both start_time entries 08:00:00 and 09:00:00 exists.
I tried to use this SQL query:
$sqlquery = mysqli_query($myconnection,"SELECT date
FROM mytable
WHERE start_time LIKE '08:00:00'
AND '09:00:00'") or die ("crashed");
But it returns me both dates 2015-12-25 and 2015-12-30. It should only return 2015-12-30 because for this date 08:00:00 and 09:00:00 exists.
I want to select those dates which have an entry for 08:00:00 and 09:00:00 too.
It should not select dates with only an entry for 08:00:00 but none for 09:00:00 and also not those which have an entry for 09:00:00 but none for 08:00:00.
Don't use like for date/time columns. Here, you seem to want between:
SELECT date
FROM mytable
WHERE start_time BETWEEN '08:00:00' AND '09:00:00';
Your original formulation is parsed like this:
WHERE (start_time LIKE '08:00:00') AND '09:00:00'
The second part is a string value in a boolean/integer context. It gets converted to 9, which is always true. So, the where clause ends up being equivalent to:
WHERE start_time = '08:00:00'
EDIT:
Your clarification changes my understanding of the question. If you want days that have both times, use aggregation:
SELECT date
FROM mytable
WHERE start_time IN ('08:00:00', '09:00:00')
GROUP BY date
HAVING COUNT(*) = 2;
i assume that you basically want to select date that has both '08:00:00' and '09:00:00', then you should not use 'BETWEEN'.
try this query:
SELECT t1.date
FROM mytable AS t1
INNER JOIN mytable AS t2 ON t1.date = t2.date
INNER JOIN mytable AS t3 ON t1.date = t3.date
INNER JOIN mytable AS t4 ON t1.date = t4.date
WHERE t1.start_time = '08:00:00'
AND t2.start_time = '09:00:00'
AND t3.start_time = '10:00:00'
AND t4.start_time = '11:00:00'
GROUP BY t1.date
or you can try another approach
SELECT t1.date
FROM mytable AS t1
GROUP BY t1.date
HAVING SUM(IF(t1.start_time = '08:00:00', 1, 0)) > 0
AND SUM(IF(t1.start_time = '09:00:00', 1, 0)) > 0
AND SUM(IF(t1.start_time = '10:00:00', 1, 0)) > 0
AND SUM(IF(t1.start_time = '11:00:00', 1, 0)) > 0
As mentioned in the comments there are different ways to achieve it depending on what you actually want to do with the result.
Easy->Just count the records with specific dates
select date, count(start_time)
from mytable
group by date
having count(start_time) > 1
2.Advanced->Display the records by using a case
select *
from (
Select date,
case when start_time = '08:00:00' then 1 end as startat8,
case when start_time = '09:00:00' then 1 end as startat9
from mytable
) a
where a.startat8=1 and a.startat9=1;
I have a visit table with user_id and visited_at columns. I would like to find how many are new and repeat customer in this month.
user_id visited_at
--------------------------------------------------------------------------
1750 2015-04-06 10:39:20
1870 2015-04-05 15:48:11
1990 2015-04-04 12:38:35
1920 2015-04-03 10:18:21
1080 2015-04-01 10:18:21
1750 2015-01-28 12:38:59
1920 2015-01-19 17:20:20
1920 2015-01-17 15:10:10
1080 2015-01-13 20:18:41
1920 2014-04-04 10:31:15
1750 2013-10-04 10:39:20
In January 2015, user 1750 and 1920 visited the same place so total repeated customers are 2. In April 2015, user 1750, 1920 and 1080 visited the same place so total repeated customers are 3. The output should be something like this
Month New Repeat
----------------------------------------------
October 2013 1 0
April 2014 1 0
January 2015 1 2
April 2015 2 3
One approach is to get the date of the first visit for each user using a subquery. Then join in this information, and use count(distinct) to count the number of users:
select year(v.visited_at) as yyyy, month(visited_at) as mm,
count(distinct user_id) as num_users,
count(case when v.visited_at = vv.minva then user_id end) as num_new_users
from visits v join
(select user_id, min(visited_at) as minva
from visits t
group by user_id
) vv
on v.user_id = vv.user_id
group by year(v.visited_at), month(visited_at)
order by year(v.visited_at), month(visited_at);
I note that this gives the total and new users; the repeats are the difference.
Something like this will work:
SELECT * FROM table_name WHERE updated_at >= CAST('2014-02-01' AS DATE) AND updated_at <= CAST('2014-02-28' AS DATE);
SELECT
MONTH(created_at) as _Month,
YEAR(created_at) as _Year,
COUNT(*) as New
FROM
yourtable
GROUP BY 0,1
You can also filter results using where clause.
I need report of products amount, between month and years...
am use this query but fetch amount is 0
SELECT SUM(amount) as amt
FROM `products`
WHERE `cid`='14'
AND `sid`='24'
AND MONTH(`date`)='03'
AND YEAR(`date` BETWEEN '2014' AND '2016')
Try this: (will bring data from 03/2014, 03/2015, 03/2016)
SELECT SUM(amount) as amt
FROM `products`
WHERE `cid`='14'
AND `sid`='24'
AND MONTH(`date`)='03'
AND YEAR(`date`) BETWEEN '2014' AND '2016'
If you want to bring all data between these two dates, try this:
SELECT SUM(amount) as amt
FROM `products`
WHERE `cid`='14'
AND `sid`='24'
AND `date` >= '2014-03-01 00:00:00' AND `date` < '2016-04-01 00:00:00'
Try this Query:-[Tested myself]
Table Data-
id cid sid amount date
1 14 24 200 2014-03-09
2 14 24 30 2014-03-09
3 14 24 50 2015-05-08
Query:-
SELECT SUM(amount) as amt FROM products WHERE cid='14' AND sid='24' AND MONTH(date)='3' AND YEAR(date) BETWEEN '2014' AND '2016'
Output:-
amt
230
Note:- Make sure your Date column's datatype is DATE
This has me a stummped...
If I have a this MySQL table:
UserId | Commission | Date Of Commission
1 | 200.00 | 2014-02-12
1 | 50.00 | 2014-04-01
2 | 10.00 | 2014-04-05
and I would like to display the Total Commission for a specific user per week starting from his/her first record, and display 0 for that range if there's no record.
how would I go about it?
Sample Output
UserId | Date Range | Total Commission
1 | 02/10/14 - 02/16/14 | 200.00
1 | 02/17/14 - 02/23/14 | 0.00
...
1 | 03/31/14 - 04/06/14 | 50.00
I'm not a seasoned coder so any help will be much appreciated.
Thanks!
Edit:
I have tried this:
SELECT IFNULL(SUM(Commisssion),0) Total ,DATE_SUB(`DateOfCommission`,INTERVAL 7 DAY)
AS RangStart,DATE_SUB(`DateOfCommission`,INTERVAL 1 DAY) AS RangeEnd
FROM `comms` WHERE `UserId` = '$UserID' GROUP BY DATE(`DateOfCommission`) DESC
but it starts the week with whatever date the first record was entered..
This is very tricky to accomplish. Here is what I managed to do with small modifications it should work they way it needs to be. I have done it for userid = 1 and this could be done for other users as well.
In the query I have 2 lines
where a.Date BETWEEN (select min(date) from transactions where UserId = 1) AND NOW()
and
WHERE date BETWEEN (select min(date) from transactions where UserId = 1) AND NOW()
The query will try to generate the list of dates using the min() date of transaction for the user till today. Instead of now() this could be used as max() date of transaction for the user as well.
select
t1.date_range,
coalesce(SUM(t1.Commission+t2.Commission), 0) AS Commission
from
(
select
a.Date as date,
concat(
DATE_ADD(a.Date, INTERVAL(1-DAYOFWEEK(a.Date)) +1 DAY),
' - ',
DATE_ADD(a.Date, INTERVAL(7- DAYOFWEEK(a.Date)) +1 DAY)
) as date_range,
'0' as Commission
from (
select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as date
from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) a
where a.Date BETWEEN (select min(date) from transactions where UserId = 1) AND NOW()
)t1
left join
(
SELECT date ,
coalesce(SUM(Commission), 0) AS Commission
FROM transactions
WHERE date BETWEEN (select min(date) from transactions where UserId = 1) AND NOW()
AND UserId = 1
GROUP BY date
)t2
on t2.date = t1.date
group by t1.date_range
order by t1.date_range asc
DEMO
So, this is sort of an algorithm you could use:
$Result = select distinct userid from table(this will fetch all userids from table)
while(There are rows in $Result)
{
$Userid = $Result['userid']
$StartDateRes = mysql_query(select Date, WEEKOFYEAR(Date) as week from table where userid = Userid order by date asc limit 1)
$StartDateRow = mysql_fetch_assoc($StartDateRes)
$StartDate = $StartDateRes['Date']
$StartWeekNumber = $StartDateRes['week']
$EndDateRes = mysql_query(select Date, WEEKOFYEAR(Date) as week from table where userid = Userid order by date desc limit 1)
$EndDateRow = mysql_fetch_assoc($EndDateRes)
$EndDate = $EndDateRes['Date']
$EndWeekNumber = $EndWeekRes['week']
for($i=$StartWeekNumber; $i<=$EndWeekNumber; $i++)
{
$StartDateOfWeek = FuncToFindStartDateOfWeek($i)
$EndDateOfWeek = FuncToFindEndDateOfWeek($i)
$Result2 = mysql_query(select sum(commission) as sum from table where date between StartDateOfWeek and EndDateOfWeek group by userid)
$Row2= mysql_fetch_assoc($Result2)
$Sum = $Row2['sum']
mysql_query("insert into OutputTable values($UserId, $StartDateOfWeek. '-'. $EndDateOfWeek ,$Sum");
}
}
SELECT UserId, COALESCE(SUM(Commission),0), YEARWEEK(DateOfCommission) AS TheWeek
GROUP BY UserId, TheWeek
ORDER BY UserId, TheWeek;
This will not print the nice date range, but should get you started in a SQL-only direction where the sum is broken down by the week of the year. I think you could take it from this point to add the nicer formatting of the Year/Week column. YEARWEEK() should give you pretty fast results.
The easiest way I can think of doing this as follows
Step 1: Get the date of the first record
"SELECT dateofcommission FROM comissionstable WHERE id='userid' ORDER BY dateofcommission ASC LIMIT 1"
The above query will return the first date of commission only
Step 2: Create a loop which starts from the date you got in Step 1 and continue the loop till the date is greater than or equal to today's date. Increment this date using PHP date function.
date('Y-m-d', strtotime($dateofcommission. ' + 7 days'));
Step 3: In this loop you can get the commission with-in the starting date and ending date. Starting date will be the date before adding 7 days and ending date will be the one after you have added 7 days.
SELECT SUM(commission) FROM commissiontable WHERE dateofcommission>= startingdate AND dateofcomission < endingdate AND id='userid'
The above logic should work. If you end up having some issues with this logic feel free to post in comments. I would be happy to help
The following is another solution
function getStartAndEndDate($week, $year) {
$time = strtotime("1 January $year", time());
$day = date('w', $time);
$time += ((7*$week)+1-$day)*24*3600;
$return[0] = date('Y-n-j', $time);
$time += 6*24*3600;
$return[1] = date('Y-n-j', $time);
return $return;
}
$query = mysqli_query($con, "SELECT userid, COALESCE( SUM( commission ) , 0 ) AS thecommission , YEARWEEK( doc ) AS TheWeek FROM commission GROUP BY userid, TheWeek ORDER BY userid, TheWeek");
while ($array = mysqli_fetch_array($query)) {
$test = $array['TheWeek'];
$store_array = getStartAndEndDate(substr($test,4,2), substr($test,0,4));
echo $array['userid']."-".$array['thecommission']."-".$store_array[0]."/".$store_array[1]."<br>";
}
Hotel_id Room_id Room_type Start_date End_date Price
----------------------------------------------------------------
13 2 standard 2012-08-01 2012-08-15 7000
13 2 standard 2012-08-16 2012-08-31 7500
13 2 standard 2012-09-01 2012-09-30 6000
13 3 luxury 2012-08-01 2012-08-15 9000
13 3 luxury 2012-08-16 2012-08-31 10000
13 3 luxury 2012-09-01 2012-09-30 9500
Hi this is the structure and data of my table.
I need to create a mysql query for hotel booking, that would match in database user entered data:
Date when they want to checkin and checkout
Room type
For Ex:
If user selects Hotel with luxury room based on these dates (2012-08-30 to 2012-09-04)
the total cost would be (10000*2) for 30th and 31st Aug + (9500*3) for 1st,2nd and 3rd Sep(4th checkout day don't include)
that means total price will be 20000+28500=48500
So query should filter total price based on the Hotel_id,Room_id,Start_date,End_date and Price
Thanks
Use this solution:
SELECT SUM(
CASE WHEN a.Start_date = b.min_sd AND a.Start_date <> b.max_sd THEN
(DATEDIFF(a.End_date, '2012-08-30')+1) * a.Price
WHEN a.Start_date = b.max_sd AND a.Start_date <> b.min_sd THEN
DATEDIFF('2012-09-04', a.Start_date) * a.Price
WHEN (a.Start_date,a.Start_date) IN ((b.min_sd,b.max_sd)) THEN
(DATEDIFF('2012-09-04', '2012-08-30')+1) * a.Price
WHEN a.Start_date NOT IN (b.min_sd, b.max_sd) THEN
(DATEDIFF(a.End_date, a.Start_date)+1) * a.Price
END
) AS totalprice
FROM rooms a
CROSS JOIN (
SELECT MIN(Start_date) AS min_sd,
MAX(Start_date) AS max_sd
FROM rooms
WHERE Room_type = 'luxury' AND
End_date >= '2012-08-30' AND
Start_date <= '2012-09-04'
) b
WHERE a.Room_type = 'luxury' AND
a.End_date >= '2012-08-30' AND
a.Start_date <= '2012-09-04'
Replace occurances of 2012-08-30 and 2012-09-04 with your input start and end dates respectively.
This will account for start and end dates being in the same month as well as spanning across multiple months.
SQLFiddle Demo
You can use MySQL's BETWEEN ... AND ...
operator to find the date ranges in which the desired booking falls (remember to take one day off of the given checkout
date as, like you say, there is no night's stay), then group the results by room and take the
SUM() of price times number of nights (which can
be calculated using MySQL's LEAST() and
GREATEST() functions):
SELECT Room_id,
SUM(Price * (1 + DATEDIFF(
LEAST(End_date, '2012-09-04' - INTERVAL 1 DAY),
GREATEST(Start_date, '2012-08-30')
))) AS Total
FROM mytable
WHERE Room_type = 'luxury' AND (
'2012-09-04' - INTERVAL 1 DAY
BETWEEN Start_date AND End_date
OR '2012-08-30' BETWEEN Start_date AND End_date
)
GROUP BY Room_id
See it on sqlfidde.
try this:
set #Hotel_id :=13;
set #Room_id :=3;
set #Start_date :='2012-08-30' ;
set #End_date :='2012-09-04';
select sum(b.TotalPrice-b.deductions) as total_cost from
( select a.Price,a.StartDate,a.EndDate,price*(DATEDIFF(a.EndDate,a.StartDate)+1) as TotalPrice
,case when a.EndDate=#End_date then a.Price else 0 end as deductions
from
(select price,case when #Start_date>=Start_date then #Start_date else Start_date end as StartDate
,case when #End_date<=End_date then #End_date else End_date end as EndDate
from h_booking h1
where Hotel_id=#Hotel_id
and Room_id=#Room_id
and (#Start_date between Start_date and End_date or #End_date between Start_date and End_date ))a )b