Rewrite query with union in subquery by using gorm - sql

I am trying to write sql query by using gorm. Here the query
SELECT *
FROM (
SELECT unnest(tags) as tag_name FROM models
union all
SELECT unnest(system_tags) from models
left join projects on projects.id = models.project_id
WHERE (projects.is_public = true )) as tD
WHERE LOWER( tD.tag_name ) LIKE '%12%' ORDER BY tag_name
I tried to create subquery. But cant figure out how to add union. As I understand select does not work this way. Is using Raw() my only option?
selectStr := "unnest(tags) as tag_name from models union select unnest(system_tags) from models"
subQuery = db.
Model(&tagsGet).
Select(selectStr).
Joins(joinStrProjects).
Where(whereClause, args...)

Related

Converting Nested SQL to ORM in Django

I have a Query Like this
SELECT
*,
(
SELECT
COALESCE(json_agg(product_attribute), '[]')
FROM
(
SELECT
*
FROM
optimus_productattribute as product_attribute
WHERE
product.id = product_attribute.product_id
)
AS product_attribute
)
AS product_atttribute
FROM
optimus_product as product inner join optimus_store as store on product.store_id = store.id
and I want to convert it to ORM
Have Tried JSONBAgg but it says it can only be used to have Single Column
Product.objects.filter(store_id=787).annotate(attributes=Coalesce(JSONBAgg(ProductAttribute.objects.filter(product=OuterRef('pk')).values_list('id', 'uuid')),[]))

How can I change "join with select statement results to" laravel eloquent?

My query like this :
SELECT
*
FROM
(SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks) t1
INNER JOIN
(SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks) t2
ON t1.ks = t2.ks
I want to change it to laravel eloquent. I need to using paginate method from laravel eloquent
I try like this :
$query = \DB::select(\DB::raw("
SELECT *
FROM (
SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks
) t1
INNER JOIN (
SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks
) t2 ON t1.ks = t2.ks
"));
I'm confused to put paginate method. I need it. Because I want display pagination in view blade laravel
The script like this : {{ $results->appends(Request::query())->render() }}
How can I do it?
Firstly, based on the linked question from which you sourced your database schema, the data you are attempting to query can be found using a far simplier query.
I have written the following query for use on a MySQL DBMS, as neither your, nor the linked question specify a DBMS type.
SELECT ks, COUNT(*) AS tasks, SUM(age < palt) AS late
FROM tasks
GROUP BY ks;
Here's an SQL Fiddle with sample data demonstrating the query works.
Secondly, the aforementioned query can be built using the Laravel query builder as follows.
$results = DB::table('tasks')
->selectRaw('ks, COUNT(*) AS tasks, SUM(age < palt) AS late')
->groupBy('ks')
->paginate(10);

Laravel 4.2 execute query without using elequent query builder

I have a query with sub-query .. and i want to write an explicite SQL request and execute it
Query :
select count(*) as count from
(
SELECT DISTINCT t.article_id FROM
`articles` as a left join `tags` as t
on a.`id` = t.`article_id`
where a.`flag` = 1
) as sub
i tried this to execute the request without building the query :
DB::connection()->getPdo()->exec( $sql );
But it always return 0 !
You can use sub query with DB::raw.
A method DB::raw() (don’t forget to use Illuminate\Support\Facades\DB) allows you to select whatever you want and basically write raw SQL statements.
DB::select(DB::raw("select count(*) as count from
(
SELECT DISTINCT t.article_id FROM
`articles` as a left join `tags` as t
on a.`id` = t.`article_id`
where a.`flag` = 1
) as sub"));
https://laravel.com/docs/4.2/queries#raw-expressions
Why don't you try with DB::raw('your sql query here')
Using DB::select should solve your problem.
DB::select('select count(*) as count from
(
SELECT DISTINCT t.article_id FROM
`articles` as a left join `tags` as t
on a.`id` = t.`article_id`
where a.`flag` = 1
) as sub');

sql inner table substitution

Suppose I have an sql query like the following (I realize this query could be written better, just bear with me):
SELECT aT.NAME
FROM anothertable aT,
( SELECT ts.slot_id,
tgm.trans_id,
tagm.agent_id
FROM slots ts,
transactions tgm,
agents tagm
WHERE ts.slot_id = (12345, 678910)
and ts.slot_id = tagm.slot_id
AND ts.slot_id = tgm.slot_id) INNER
WHERE INNER.trans_id = aT.trans_id
AND INNER.agent_id = aT.trans_id
Now suppose that I need to break up this query into two parts...in the first I'll execute the inner query, do some processing on the results in code, and then pass back a reduced set to the outer part of the query. The question is, is there an easy way to emulate an inner table in sql?
For instance, if the results of the inner query returned 5 rows but my program deems to only need two of those rows, how can I write sql that will do what I am trying to do below? Is there a way, in sql, to declare a table for in memory in query use?
SELECT
at.Name
FROM
anotherTable aT,
(SLOT_ID, TRANS_ID, AGENT_ID
-------------------------
230743, 3270893, 2307203
078490, 230897, 237021) inner
WHERE
inner.trans_id = at.trans_id
AND INNER.agent_id = aT.trans_id
Just use a subquery:
SELECT at.Name
FROM anotherTable aT JOIN
(select 230743 as SLOT_ID, 3270893 as TRANS_ID, 2307203 as AGENT_ID from dual
select 078490, 230897, 237021 from dual
) i
on i.trans_id = at.trans_id AND i.agent_id = aT.trans_id;
Most systems will let you define a TEMP TABLE or TABLE VARIABLE: https://www.simple-talk.com/sql/t-sql-programming/temporary-tables-in-sql-server/
CREATE TABLE #temp (
SLOT_ID INT,
TRANS_ID INT,
AGENT_ID INT
);
INSERT INTO #temp(SLOT_ID, TRANS_ID, AGENT_ID)
(--inner query goes here)
--do your main query, then:
DROP TABLE #temp
IN MS SQL Server (not sure about other systems), you could possibly use a Common Table Expression (CTE): https://technet.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx
WITH inner AS (
--inner query goes here
)
--main select goes here
Personally, since I generally work with MSSQL Server, I use CTE's quite a bit, as they can be created "on the fly", and can be a big help in organizing more complex queries.
The subquery method worked. Since this is Oracle, the syntax turned out to be:
SELECT aT.Name
FROM anotherTable aT,
(select 1907945 as SLOT_ID, 2732985 as TRANS_ID, 40157 as AGENT_ID FROM DUAL
union
select 1907945, 2732985, 40187 FROM DUAL
) inner
WHERE
inner.trans_id = aT.trans_id AND INNER.agent_id = aT.trans_id;

Best performance solution for SELECT ... FROM UNION

I have got two products tables, let's say current_products and historical_products, with the very same structure, and a key in the product_code field.
I have to search a list of product in these tables for further processing.
The trivial solution I've figured out is the following:
SELECT u.*
, u.calculated_fields
, t.other_fields
FROM (
SELECT * FROM current_products
UNION
SELECT * FROM historical_products
) u
JOIN other_tables t
WHERE u.product_code = 'some_prodcut_code'
PROS: DRY
CONS: bad performance
The performance are not the best, so I would like to create a conditional query like this:
IF EXISTS (select * from current_products WHERE product_code = 'some_prodcut_code')
BEGIN
SELECT u.*
, u.calculated_fields
, t.other_fields
FROM current_products u
JOIN other_tables t
WHERE u.product_code = 'some_prodcut_code'
END
ELSE IF EXISTS (select * from historical_products WHERE product_code = 'some_prodcut_code')
BEGIN
SELECT u.*
, u.calculated_fields
, t.other_fields
FROM historical_products u
JOIN other_tables t
WHERE u.product_code = 'some_prodcut_code'
END
PROS: better performance
CONS: NOT DRY
QUESTION
Is there a third way?
performance killing you because you are pulling all records from both table first, THEN applying the where condition... try changing to
FROM (
SELECT * FROM current_products
WHERE product_code = 'some_prodcut_code'
UNION
SELECT * FROM historical_products
WHERE product_code = 'some_prodcut_code'
) u
JOIN other_tables t
This way, the internal query can work against the indexes of the underlying products tables (presuming you HAVE an index on the product_code in the first position, or with other criteria you may want to also apply).