I have written different queries that function for different things. I want to combine them as one (Sales for: Today, Current Week, Current Week, Current Month, Current Year and Overall Sales) and Group By a field called store.
$currentYear = date('y');
$currentyearbilling = DB::table("billings")
->select(DB::raw("SUM(amount) as total"))
->whereRaw('YEAR(created_at) = ?',$currentYear)
->get();
$currentMonth = date('m');
$currentmonthbilling = DB::table("billings")
->select(DB::raw("SUM(amount) as total"))
->whereRaw('MONTH(created_at) = ?',$currentMonth)
->get();
$currentWeek = date('w');
$currentweekbilling = DB::table("billings")
->select(DB::raw("SUM(amount) as total"))
->whereRaw('WEEK(created_at) = ?',$currentWeek)
->get();
$currentDay = date('d');
$currentdaybilling = DB::table("billings")
->select(DB::raw("SUM(amount) as total"))
->whereRaw('(created_at) = ?',$currentDay)
->get();
Group By store.
The table name is called billings. I still want to follow this format
DB::table("billings")
How do I achieve this?
Error:
You should try this:
$currentYear = date('y');
$currentMonth = date('m');
$currentWeek = date('w');
$currentDay = date('d');
$currentyearbilling = DB::table("billings")
->select(DB::raw("SUM(amount) as total"))
->whereRaw('YEAR(created_at) = ?',$currentYear)
->orWhereRaw('MONTH(created_at) = ?',$currentMonth)
->orWhereRaw('WEEK(created_at) = ?',$currentWeek)
->orWhereRaw('(created_at) = ?',$currentDay)
->groupBy('store')
->get();
Lets say we have a table billings like this:
| column | type |
|------------|------------|
| id | int |
| store | varchar |
| amount | int |
| created_at | timestamps |
| updated_at | timestamps |
I will get amount of every store in current_day, current_month, current_week, current_year, and overall by using sub query like this:
select
store,
(SELECT SUM(amount) from billings as child where child.store = parent.store and DAY(created_at) = ? and MONTH(created_at) = ? and YEAR(created_at) = ?) as current_day,
(SELECT SUM(amount) from billings as child where child.store = parent.store and WEEK(created_at) = ?) as current_week,
(SELECT SUM(amount) from billings as child where child.store = parent.store and MONTH(created_at) = ? and YEAR(created_at) = ?) as current_month,
(SELECT SUM(amount) from billings as child where child.store = parent.store and YEAR(created_at) = ?) as current_year,
SUM(amount) as overall,
COUNT(id) as total_rows
from billings as parent
group by store
And with Eloquent, it would be just something like this:
$childQuery = \DB::table(\DB::raw('billings as child'))
->select(\DB::raw('SUM(amount) as amount'))
->whereRaw('child.store = parent.store');
$currentDayQuery = (clone $childQuery)->whereDay('created_at', now()->day)->whereMonth('created_at', now()->month)->whereYear('created_at', now()->year);
$currentWeekQuery = (clone $childQuery)->where(\DB::raw('WEEK(created_at)'), now()->weekOfYear);
$currentMonthQuery = (clone $childQuery)->whereMonth('created_at', now()->month);
$currentYearQuery = (clone $childQuery)->whereYear('created_at', now()->year);
$rows = \DB::table(\DB::raw('billings as parent'))
->select([
'store',
\DB::raw('(' . $currentDayQuery->toSql() . ') as current_day'),
\DB::raw('(' . $currentWeekQuery->toSql() . ') as current_week'),
\DB::raw('(' . $currentMonthQuery->toSql() . ') as current_month'),
\DB::raw('(' . $currentYearQuery->toSql() . ') as current_year'),
\DB::raw('SUM(amount) as overall'),
\DB::raw('COUNT(id) as total_rows')
])
->mergeBindings($currentDayQuery)
->mergeBindings($currentWeekQuery)
->mergeBindings($currentMonthQuery)
->mergeBindings($currentYearQuery)
->groupBy('store')
->get();
Hope this helps.
Related
I have a query like this. How should I convert it into a eloquent or query builder
SELECT
x.MATERIAL_ID,
(SELECT TAPET_NAME FROM MA_TAPE_TYPE WHERE TAPET_CODE = x.MATERIAL_TYPE) as media_type,
(SELECT TAPEF_NAME FROM MA_TAPE_FORMAT WHERE TAPEF_CODE = x.MATERIAL_FORMAT) as media_format,
STOCK_MATERIAL_EPI.HOUSE_NO,
x.TXN_DATE,
STOCK_MATERIAL_EPI.PROGRAM_NAME,
CASE WHEN x.iden_flag = 'P' THEN STOCK_MATERIAL_EPI.epi_title WHEN x.iden_flag = 'C'
THEN STOCK_MATERIAL_EPI.prod_version_name WHEN x.iden_flag = 'M' THEN STOCK_MATERIAL_EPI.promo_name
END as episode_title,
PUR_EPISODE_HDR.EPI_NO,
(SELECT MAX (last_date) FROM run_master WHERE run_master.row_id_epi = PUR_EPISODE_HDR.row_id AND
run_master.run_aired = 'Y') as last_tx,
x.REMARKS,
x.LOCATION_ID as shelf_no,
stock_material_slag.remarks as short_list
FROM STOCK_MATERIAL x
LEFT JOIN STOCK_MATERIAL_EPI ON x.MATERIAL_ID = STOCK_MATERIAL_EPI.MATERIAL_ID
LEFT JOIN stock_material_slag ON x.MATERIAL_ID = stock_material_slag.MATERIAL_ID
LEFT JOIN PUR_EPISODE_HDR ON STOCK_MATERIAL_EPI.ROW_ID_EPI = PUR_EPISODE_HDR.ROW_ID
I'm confused as to how to convert them. Can someone help me.
I tried to write like this.
But it doesn't work,
$materials = DB::connection('oracle')
->table('STOCK_MATERIAL AS x')
->select('x.MATERIAL_ID',
DB::raw("(SELECT TAPET_NAME FROM MA_TAPE_TYPE WHERE TAPET_CODE = x.MATERIAL_TYPE) as MEDIA_TYPE"),
DB::raw("(SELECT TAPEF_NAME FROM MA_TAPE_FORMAT WHERE TAPEF_CODE = x.MATERIAL_FORMAT) as MEDIA_FORMAT"),
'x.TXN_DATE',
'y.HOUSE_NO', 'y.PROGRAM_NAME',
DB::raw("(CASE WHEN x.IDEN_FLAG = 'P' THEN z.EPI_TITLE WHEN x.IDEN_FLAG = 'C' THEN z.PROD_VERSION_NAME WHEN x.IDEN_FLAG = 'M' THEN z.PROMO_NAME END as EPISODE_TITLE)"),
'w.EPI_NO',
DB::raw("(SELECT MAX (LAST_DATE) FROM RUN_MASTER WHERE RUN_MASTER.ROW_ID_EPI = w.ROW_ID AND RUN_MASTER.RUN_AIRED = 'Y') as LAST_TX"),
'z.REMARKS',
'x.LOCATION_ID as SHELF_NO',
'z.REMARKS'
)
->leftJoin('STOCK_MATERIAL_EPI AS y', 'y.MATERIAL_ID', '=', 'x.MATERIAL_ID')
->leftJoin('STOCK_MATERIAL_SLAG AS z', 'z.MATERIAL_ID', '=', 'x.MATERIAL_ID')
->leftJoin('PUR_EPISODE_HDR AS w', 'w.ROW_ID', '=', 'y.ROW_ID_EPI')
What else do I write right?
You would need to define eloquent models and then use with(). Documentation can be found at the link below: https://laravel.com/docs/7.x/eloquent-relationships#constraining-eager-loads
example
StockMaterial::with([
'maTapeType' => function($query) {
$query->get('name')
})
])
For Query Builder you DB::raw and DB::leftJoin to create the same query.
DB::from('STOCK_MATERIAL')
->selectRaw([
'TAPET_NAME as media_type',
'CASE WHEN x.iden_flag = "P" THEN STOCK_MATERIAL_EPI.epi_title
WHEN x.iden_flag = "C" THEN STOCK_MATERIAL_EPI.prod_version_name
WHEN x.iden_flag = "M" THEN STOCK_MATERIAL_EPI.promo_name
END as episode_title',
])
->leftJoin('MA_TAPE_TYPE', 'TAPET_CODE', 'STOCK_MATERIAL.MATERIAL_TYPE')
https://laravel.com/docs/7.x/queries#raw-expressions
https://laravel.com/docs/7.x/queries#joins
SELECT fp.id, fp.name, fp.slug, fp.status, fc.name, fc.slug as category_slug, fp.approved, ff.filepath, fdp.product_id,fdp.type, fdp.sku, fdp.regular_price, fdp.sale_price, fp.created_at, fp.updated_at
FROM `foduu_products` fp
JOIN `foduu_details_product` fdp ON fp.id= fdp.product_id
JOIN `foduu_category_product` fcp ON fp.id = fcp.product_id
JOIN `foduu_filemanager` ff ON fp.filemanager_id = ff.id
JOIN `foduu_categories` fc ON fcp.category_id = fc.id
WHERE fc.slug= "microsoftheadphonesadaptersmotherboardswebcam"
AND fp.approved = 1
AND fp.status = 1
This code should work according to your logic:
$match = ['fc.slug' => 'microsoftheadphonesadaptersmotherboardswebcam', 'fp.approved' => '1', 'fp.status'=>'1'];
$result = DB::table('foduu_products as fd')
->join('foduu_details_product as fdp','fp.id','=','fdp.product_id')
->join(......
.............
->where($match)
->select('fp.id', 'fp.name', ...................)
->get();
I have a date column in the instances table with varchar datatype stored as d-m-Y. In my where condition I am trying to fetch records for just past 30 days only.
$backdate = Carbon::parse('-30 days')->toDateString();
$date30DaysBack = Carbon::parse($backdate)->format('d-m-Y');
$adverts = DB::table('adverts')
->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=',$date30DaysBack)
The full query
$adverts = DB::table('adverts')
->select(DB::raw('(SELECT IF(ext = \'jpeg\', CONCAT(fullpath, \'_1.\', ext), (CONCAT(fullpath,\'.\',ext))) as fullpath FROM advertsstorage where uid_dir = adverts.ad_uid ORDER BY id ASC limit 1)as fullpath, adverts.*, domains.location,instances.date'))
->join('domains','adverts.domain', '=' ,'domains.domain')
->join('advertiser_domains','domains.id', '=' ,'advertiser_domains.domain_id')
->join('advertisers','advertiser_domains.advertiser_id', '=' ,'advertisers.u_id')
->join('instances','adverts.ad_uid','=','instances.ad_uid')
->join('urls','instances.u_id','=','urls.id')
->join('sites','urls.sites_id','=','sites.id')
->where('advertisers.u_id', '=',$advertiserID)
->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=',Carbon::now()->subDays(30)->format('d-m-Y'))
->orderBy(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), 'DESC')
->get();
Did you try DATEDIFF method
$adverts = DB::table('adverts')
->select(DB::raw('(SELECT IF(ext = \'jpeg\', CONCAT(fullpath, \'_1.\', ext), (CONCAT(fullpath,\'.\',ext))) as fullpath FROM advertsstorage where uid_dir = adverts.ad_uid ORDER BY id ASC limit 1)as fullpath, adverts.*, domains.location,instances.date'))
->join('domains','adverts.domain', '=' ,'domains.domain')
->join('advertiser_domains','domains.id', '=' ,'advertiser_domains.domain_id')
->join('advertisers','advertiser_domains.advertiser_id', '=' ,'advertisers.u_id')
->join('instances','adverts.ad_uid','=','instances.ad_uid')
->join('urls','instances.u_id','=','urls.id')
->join('sites','urls.sites_id','=','sites.id')
->where('advertisers.u_id', '=',$advertiserID)
->where(DB::raw('DATEDIFF( now(), STR_TO_DATE(instances.date,"%d-%m-%Y") )'), '<=', 30)
->orderBy(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), 'DESC')
->get();
Have you checked out the Carbon docs?
You can use the subtraction modifier for this; Carbon::now()->subDays(30);.
Would look something like this in your code:
$adverts = DB::table('adverts')->where(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'), '>=', Carbon::now()->subDays(30)->format('d-m-Y'))
Try this.
Carbon has subDays function by which you can get past 30 days data
$date30DaysBack= Carbon::now()->subDays(30)->format('d-m-Y');
$today = Carbon::now()->format('d-m-Y');
$adverts = DB::table('adverts')
->whereBetween(DB::raw('STR_TO_DATE(instances.date,"%d-%m-%Y")'),[$date30DaysBack,$today])->get()
I'm trying to create an Eloquent query that gets the total number of posts made each distinct day, and if the date is missing, fill it in with a value of zero.
For example, if my table looks like this:
+----+---------------------+
| id | date |
+----+---------------------+
| 1 | 2015-01-01 00:00:00 |
| 2 | 2015-01-01 01:53:18 |
| 3 | 2015-01-01 02:41:26 |
| 4 | 2015-01-02 12:51:01 |
| 5 | 2015-01-05 08:24:12 |
+----+---------------------+
This would output:
2015-01-01 : 3
2015-01-02 : 1
2015-01-05 : 1
Notice, however, that the days 03-04 are missing. How can I include these dates, but give them the value 0 such that I end up with an output like:
2015-01-01 : 3
2015-01-02 : 1
2015-01-03 : 0
2015-01-04 : 0
2015-01-05 : 1
Here is my current query:
$posts = Post::select(array(
DB::raw('DATE(`created_at`) as `date`'),
DB::raw('COUNT(*)as `count`')
))
->where('created_at', '>', Carbon::today()->subWeek())
->groupBy('date')
->orderBy('date', 'DESC')
->lists('count', 'date');
Thanks!
In your SQL results you can generate some "fake-data" in your rows, but u can not generate "fake-rows", exept joining to some "fake(temporary)-table".
In your case ll be much easier to apply some logic around sql-result.
Replace your code with this:
$order = 'DESC';
$endDate = Carbon::today();
$startDate = Carbon::today()->subWeek();
$dateInc = ($order == 'DESC') ? -1 : 1;
$dateCycleHolder = clone ($dateInc > 0 ? $startDate : $endDate);
$dateCycleEnd = clone ($dateInc > 0 ? $endDate : $startDate);
$posts = Post::select(array(
DB::raw('DATE(`created_at`) as `date`'),
DB::raw('COUNT(*)as `count`')
))
->where('created_at', '>', $startDate)
->groupBy('date')
->orderBy('date', $order)
->lists('count', 'date');
$postsFinal = new \Illuminate\Database\Eloquent\Collection();
while ($dateCycleHolder->ne($dateCycleEnd)) {
$dateCurr = $dateCycleHolder->format('Y-m-d');
$postsFinal->put($dateCurr, $posts->get($dateCurr, 0));
$dateCycleHolder->addDay($dateInc);
}
$dateCurr = $dateCycleHolder->format('Y-m-d');
$postsFinal->put($dateCurr, $posts->get($dateCurr, 0));
$posts = $postsFinal;
its alittle bit flexible, you can change values of this things:
$order = 'DESC';
$endDate = Carbon::today();
$startDate = Carbon::today()->subWeek();
I have following code to can sort by offers(bids and buys):
$clean_criteria = new CDbCriteria;
$clean_criteria->order = 'promoted DESC';
$criteria = new CDbCriteria;
$criteria->order = 'promoted DESC';
$criteria->select = "*, (COUNT(aa.id) + COUNT(ab.id)) as offers";
$criteria->join = ' LEFT JOIN auction_bid aa ON (t.id = aa.auction)';
$criteria->join .= ' LEFT JOIN auction_buy ab ON (t.id = ab.auction)';
I am using pagination and sort:
$item_count = Auction::model()->count($clean_criteria);
$pages = new CPagination($item_count);
$pages->setPageSize(5);
$pages->applyLimit($clean_criteria);
$sort = new CSort('Auction');
$sort->attributes = array('offers'=>array('asc'=>'offers', 'desc'=>'offers DESC'));
$sort->applyOrder($clean_criteria);
But to get offers i must use $crtieria when finding auctions:
$auctions = Auction::model()->findAll($criteria);
On site there is correct pages count, but on every there is one same auction. The problem is query return only one record, but how to fix this?
P.s Maybe i used wrong type of join and auctions which has not offers are not returned?
EDIT:
This code working properly:
$criteria->select = "*, COUNT(abid.id) AS offers1";
$criteria->join = ' LEFT JOIN auction_bid abid ON (t.id = abid.auction)';
$criteria->group = 't.id';
It returns offers1 = 1 for first auction.
Following too :
$criteria->select = "*, COUNT(abuy.id) AS offers2";
$criteria->join = ' LEFT JOIN auction_buy abuy ON (t.id = abuy.auction)';
$criteria->group = 't.id';
It returns offers2 = 4 for first auction
But when i combine it into one query:
$criteria->select = "*, COUNT(abid.id) AS offers1, COUNT(abuy.id) AS offers2";
$criteria->join = ' LEFT JOIN auction_bid abid ON (t.id = abid.auction)';
$criteria->join .= ' LEFT JOIN auction_buy abuy ON (t.id = abuy.auction)';
$criteria->group = 't.id';
It returns offers1 = 4 and offers2 = 4 for first auction.
How to fix it?
Solved:
criteria:
$criteria->select = "*, (COUNT(DISTINCT abid.id) + COUNT(DISTINCT abuy.quantity)) AS `offers`";
$criteria->join = ' LEFT JOIN auction_bid abid ON (t.id = abid.auction)';
$criteria->join .= ' LEFT JOIN auction_buy abuy ON (t.id = abuy.auction)';
$criteria->group = 't.id';
sorting:
$sort = new CSort('Auction');
$sort->attributes = array('offers');
$sort->applyOrder($criteria);
pagination:
$item_count = Auction::model()->count($clean_criteria);
$pages = new CPagination($item_count);
$pages->applyLimit($criteria);
searching:
$auctions = Auction::model()->findAll($criteria);