SQL join statement between table and selection in Knex - sql

I have SQL statement :
select from resources
left join ( select resource_id, sum(price) as PostScoreSum from
prices where '2019-06-8' < dateto and '2019-06-15' >
datefrom group by resource_id ) BB on
resources.resources_id = BB.resource_id")
Using Knex, I can write this statement as knex.raw('.....'), but after this knex statement I cannot used modify (to have chain of statements, knex.raw('...').modify...is not posible). Is it possible to write this join in Knex, between table and selection without using raw.

Not clear what actually your issue is but following will generate your above query-
const sql = knex('resources')
.leftJoin((query) => {
query
.columns([
'resource_id',
knex.raw('sum(price) as PostScoreSum')
])
.from('prices')
.where('dateto', '>', '2019-06-8')
.where('datefrom', '<', '2019-06-8')
.groupBy('resources_id')
.as('BB')
}, 'resources.resources_id', 'BB.resource_id')
.toSQL();
console.log(sql) ;

Related

MariaDB server version for the right syntax to use near 'GROUP BY

I build my project based on Laravel 9 and try to get count data by date group. I write using DB::raw to get sql query like this:
$rawActive = "
SELECT
SBC.SITE,
OPR.OPERATOR,
COUNT(*) TMO_COUNT,
DATE_FORMAT( TMO.TMO_DATE, '%m%Y' ) BULANTAHUN
FROM
TOP_TMO TMO
INNER JOIN SUBSCRIBER SBC ON TMO.SUBSCRIBER_ID = SBC.ID
INNER JOIN OPERATOR OPR ON SBC.SITE_ID = OPR.ID
WHERE
SBC.SITE_ID = ".$siteId."
GROUP BY
DATE_FORMAT(
TMO.TMO_DATE,
'%m%Y')
";
$queryAct = DB::select(DB::raw($rawActive));
the siteId is from form request.
I search for some solutions include edit 'strict' => false, in database.php , but still not find any solution.
I try to return $rawActive, and this is the result.
SELECT
SBC.SITE,
OPR.OPERATOR,
COUNT(*) TMO_COUNT,
DATE_FORMAT( TMO.TMO_DATE, '%m%Y' ) BULANTAHUN
FROM
TOP_TMO TMO
INNER JOIN SUBSCRIBER SBC ON TMO.SUBSCRIBER_ID = SBC.ID
INNER JOIN OPERATOR OPR ON SBC.SITE_ID = OPR.ID
WHERE
SBC.SITE_ID = 134
GROUP BY
DATE_FORMAT(
TMO.TMO_DATE,
'%m%Y')
As you can see, the siteId are seen well.
I also try this query on mysql, it's work fine.
Thanks for your help.
You need to adjust config\database.php as below:
'mysql' => [
...
....
'strict' => true,
'modes' => [
//'ONLY_FULL_GROUP_BY', // Disable this to allow grouping by one column
'STRICT_TRANS_TABLES',
'NO_ZERO_IN_DATE',
'NO_ZERO_DATE',
'ERROR_FOR_DIVISION_BY_ZERO',
'NO_AUTO_CREATE_USER',
'NO_ENGINE_SUBSTITUTION'
],
]
You can try this. You can enclose $siteId with single quote. '123' will work same like 123 and it will helps breaking query when there is no value assigned in $siteId. Instead try to use parameterized query that will prevent this issue and also is recommended solution for securing raw query.
$rawActive = "
SELECT
SBC.SITE,
OPR.OPERATOR,
COUNT(*) TMO_COUNT,
DATE_FORMAT( TMO.TMO_DATE, '%m%Y' ) BULANTAHUN
FROM
TOP_TMO TMO
INNER JOIN SUBSCRIBER SBC ON TMO.SUBSCRIBER_ID = SBC.ID
INNER JOIN OPERATOR OPR ON SBC.SITE_ID = OPR.ID
WHERE
SBC.SITE_ID = '".$siteId."'
GROUP BY
DATE_FORMAT(
TMO.TMO_DATE,
'%m%Y')
";
$queryAct = DB::select(DB::raw($rawActive));

cannot group with eloquent with PostreSQL

Here's my Eloquent query:
$visits = Visit::orderBy('date', 'desc')->groupBy('user_id')->get(['date', 'user_id']);
But posgreSQL is refusing the query, telling me:
SQLSTATE[42803]: Grouping error: 7 ERROR: column "visits.date" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: select "date", "user_id" from "visits" group by...
the same stuff works on MySQL when I disable ONLY_FULLY_GROUP_BY
what can I do to make it work? It would be great if I didn't have to edit configs, just the code.
This selects the latest date for each user_id:
$sub = Visit::select('user_id', DB::raw('max("date") "date"'))->groupBy('user_id');
$sql = '(' . $sub->toSql() . ') as "sub"';
$visits = Visit::join(DB::raw($sql), function($join) {
$join->on('visits.user_id', 'sub.user_id')
->on('visits.date', 'sub.date');
})->orderBy('visits.date', 'desc')->get(['visits.date', 'visits.user_id']);
If there are multiple visits for a user_id and date combination, the query returns all of them. Removing the duplicates is possible, but makes the query more complex.
It's easier to remove them afterwards:
$visits = $visits->unique('user_id');
Using postgre sql you could use distinct on user_id and order your date column to pick latest date per user_id, In laravel you could raw expression
$visits = Visit::select(DB::raw('distinct on (user_id)'), 'date')
->orderBy('date', 'desc')
->get();
Demo

Convert SQL Query with Subquery to Laravel query

Is it possible to convert my SQL Query to Laravel 4 Query
SQL:
SELECT
Branch_tbl.ID,
Branch_tbl.BranchName,
(
SELECT
SUM(Expenses.Expense)
FROM
Expenses
WHERE
Expenses.BranchID = Branch_tbl.ID
) as 'Total Expenses'
FROM
Branch_tbl
You may try raw expression (maybe it's not to best solution)
DB::table('branch_tbl')
->select(
'branch_tbl.id',
'branch_tbl.branchname',
DB::raw("
( select sum(expenses.expense) from expenses where
expenses.branchid = branch_tbl.id
)as 'total expenses'"))->get();
If you have a complex subquery you can separate it:
$subQuery = DB::table('expenses')
->select(DB::raw('sum(expenses.expense)'))
->whereRaw('expenses.branchid = branch_tbl.id');
DB::table('branch_tbl')
->select('branch_tbl.id','branch_tbl.branchname',
DB::raw("(" . $subQuery->toSql() . ") as 'total expenses'")
)
->get();
Be careful not to create any SQL injection with raw expression.

Entity framework join with a subquery via linq syntax

I'm trying to translate a sql query in linq sintax, but I'm having big trouble
This is my query in SQL
select * FROM dbo.ITEM item inner join
(
select SUM([QTA_PRIMARY]) QtaTotale,
TRADE_NUM,
ORDER_NUM,
ITEM_NUM
from [dbo].[LOTTI]
where FLAG_ATTIVO=1
group by [TRADE_NUM],[ORDER_NUM],[ITEM_NUM]
)
TotQtaLottiGroupByToi
on item.TRADE_NUM = TotQtaLottiGroupByToi.TRADE_NUM
and item.ORDER_NUM = TotQtaLottiGroupByToi.ORDER_NUM
and item.ITEM_NUM = TotQtaLottiGroupByToi.ITEM_NUM
where item.PRIMARY_QTA > TotQtaLottiGroupByToi.QtaTotale
and item.FLAG_ATTIVO=1
How can I translate into linq sintax?
This approach doesn't work
var res= from i in context.ITEM
join d in
(
from l in context.LOTTI
group l by new { l.TRADE_NUM, l.ORDER_NUM, l.ITEM_NUM } into g
select new TotQtaByTOI()
{
TradeNum = g.Key.TRADE_NUM,
OrderNum = g.Key.ORDER_NUM,
ItemNum = g.Key.ITEM_NUM,
QtaTotale = g.Sum(oi => oi.QTA_PRIMARY)
}
)
on new { i.TRADE_NUM, i.ORDER_NUM, i.ITEM_NUM} equals new { d.TradeNum, d.OrderNum, d.ItemNum }
I get this error
The type of one of the expressions in the join cluase is incorrect. Type inference failed in the call to 'Join'
Can you help me with this query?
Thank you!
The problem is Anonymous Type comparison. You need to specify matching property names for your two anonymous type's properties (e.g. first, second, third)
I tried it out, here's an example: http://pastebin.com/hRj0CMzs

How to execute query with subqueries on a table and get a Rowset object as a result in Zend?

I'm currently struggling on how to execute my query on a Table object in Zend and get a Rowset in return. Reason I need particularly THIS is because I'm modifying a code for existing project and I don't have much flexibility.
Query:
SELECT *
FROM `tblname` ud
WHERE ud.user_id = some_id
AND
(
(ud.reputation_level > 1)
OR
(
(SELECT COUNT( * )
FROM `tblname` t
WHERE t.user_id = ud.user_id
AND t.category_id <=> ud.category_id
AND t.city_id <=> ud.city_id
) = 1
)
)
Is there a way to describe this query using Select object?
Previous SQL solution was very simple and consisted of one WHERE clause:
$where = $this->getAdapter()->quoteInto("user_id = ?",$user_id);
return $this->fetchAll($where);
I need to produce same type of the result (so that it could be processed by existing code) but for more complicated query.
Things I've tried
$db = Zend_Db_Table::getDefaultAdapter();
return $db->query($sql)->fetchAll();
---------------- OR ----------------------
return $this->fetchAll($select);
---------------- OR ----------------------
return $this->_db->query($sql)->fetchAll();
But they either produce arrays instead of objects or fail with Cardinality violation message.
I would appreciate any help on how to handle SQL text queries in Zend.
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
//change the fetch mode becouse you don't like the array
$dbAdapter->setFetchMode(Zend_Db::FETCH_OBJ);
$sql = "you're long sql here";
$result = $dbAdapter->fetchAll($sql);
Zend_Debug::dump($result);
exit;
For a list of all fetch modes go to Zend_Db_Adapter
To write you're query using Zend_Db_Select instead of manual string , look at Zend_Db_Slect