Yii2 custom paginaion for Union query - pagination

I want to implement custom pagination in Yii2. this is my code
$connection = Yii::$app->getDb();
$name = $_GET['name'];
$query = '
SELECT name FROM user WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user2 WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user3 WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user4 WHERE name LIKE "%.'$name'.%""
';
$result = $connection->createCommand($query)->queryAll();
Please let me know how can i implement pagination in Yii2

Plz try this
$totalCount = 0;
$name = $_GET['name'];
$connection = Yii::$app->getDb();
$limit = 10;
$from = (isset($_GET['page'])) ? ($_GET['page']-1)*$limit : 0; // Match according to your query string
$sql = '
SELECT name FROM user WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user2 WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user3 WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user4 WHERE name LIKE "%.'$name'.%""
';
$command = $connection->createCommand($sql.' LIMIT '.$from.','.$limit);
$count = $connection->createCommand('SELECT COUNT(*) as total FROM ('.$sql.') a')->queryAll();
$result = $command->queryAll();
$totalCount = $count[0]['total'];
$pages = new Pagination(['totalCount' => $totalCount, 'pageSize' => $limit]);

Here's a more proper Yii2 way:
In Controller:
$page = Yii::$app->request->get('page', 1);
$limit = Yii::$app->request->get('per-page', 10);
$from = ($page-1)*$limit;
//Get the db connection
$db = new yii\db\Connection(Yii::$app->db);
//prepare SQL query
$sql = '
SELECT name FROM user WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user2 WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user3 WHERE name LIKE "%.'$name'.%""
UNION
SELECT name FROM user4 WHERE name LIKE "%.'$name'.%""
';
//Fire it!
$result = $db->createCommand($sql.' LIMIT '.$from.','.$limit)->queryAll();
$count = $db->createCommand('SELECT COUNT(*) as total FROM ('.$sql.') a')->->queryScalar();
$pagination = new \yii\data\Pagination(['totalCount' => $count, 'pageSize' => $limit]);
return $this->render('your-view', [
'result' => $result,
'pagination' => $pagination,
]);
Then anywhere in Your View:
echo \yii\widgets\LinkPager::widget([
'pagination' => $pagination,
]);
I myself got help from E-Avni Tech's answer. If my answer helps, please upvote him.

Related

Select distinct on joined table

I have this query
var q = Db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Join<BlogToBlogCategory, BlogCategory>()
.Where( .. )
.SelectDistinct();
var results = Db.Select<BlogCategory>(q);
It generates this SQL:
SELECT DISTINCT "blog".*, 0 EOT, "blog_category".*, 0 EOT
FROM "blog" LEFT JOIN "blog_to_blog_category" ON
("blog"."id" = "blog_to_blog_category"."blog_id") INNER JOIN "blog_category" ON
("blog_category"."id" = "blog_to_blog_category"."blog_category_id")
WHERE ...
I want to select distinct blog_category but the select is adding all the blog fields also so I am getting duplicate blog_category entries.
How do I just select distint the joined table fields?
In OrmLite the SqlExpression is what builds the SQL query you want executed:
var q = Db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Join<BlogToBlogCategory, BlogCategory>()
.Where( .. )
.SelectDistinct();
Whilst the API use to execute the query maps the result back to the specified model, in this case you're saying you want the results of the above query mapped to BlogCategory POCOs:
var results = Db.Select<BlogCategory>(q);
But you need to make sure that the query you create returns results that can map to the POCO you've specified.
If you only want to select distinct BlogCategory columns you'll need to do this in your SqlExpression:
var q = Db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Join<BlogToBlogCategory, BlogCategory>()
.Where( .. )
.SelectDistinct<BlogCategory>(c => c);
Or if you want to select columns across different joined tables you'd use a standard anonymous type expression:
var q = Db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Join<BlogToBlogCategory, BlogCategory>()
.Where( .. )
.SelectDistinct<Blog,BlogCategory>((b,c) => new { b.Id, c.Name, ... });
Then the custom model you map the results to should have properties that match the returned columns:
var results = db.Select<BlogCategoryResult>(q);
Alternatively you can access the custom result set with the Dynamic Result Set APIs.

How to get a word from a sentence using regex nodejs

I have a use case where I need to get the table name from my sql query
like suppose I have
select * from schema.tableName
OR
select * from schema.tableName where id = 123
OR
select column1, column2, column3 from schema.tableName where id = 123
In need to get 'schema.tableName' from the sql query in above cases , how it can be done using regex in Node.
I have tried (?<=from)(\s+\w+\b)
but I am getting warning that look behind is not supported in javascript.
A RegEx that will match the table name from queries similar to the ones you provided as examples can be written easily.
Try this RegEx: /select .* from ([^ ]*)/i
See the complete code below:
var sql1 = "select * from tableName";
var sql2 = "select * from tableName where id = 123";
var sql3 = "select column1, column2, column3 from tableName where id = 123";
var t1 = sql1.match(/select .* from ([^ ]*)/i);
var t2 = sql2.match(/select .* from ([^ ]*)/i);
var t3 = sql3.match(/select .* from ([^ ]*)/i);
console.log(t1[1]);
console.log(t2[1]);
console.log(t3[1]);
However, the RegEx will get complex if you would need to match table name from all the possible valid select queries.
EDIT
You can use a stripped down version of the above RegEx to get the same results.
/ from ([^ ]*)/i
Maybe something like this:
var query = "select column1, column2, column3 from schema.tableName where id = 123"
var result = query.match(/from\s+([\.\w]+)+\s+/i);
var tableName = null;
if (result && result.length > 1) {
tableName = result[1];
}

Dynamic Pivot without Null value

This is a dynamic crosstab query in Northwind database:
DECLARE #COUNTRY NVARCHAR(MAX) ='', #COUNTRY2 NVARCHAR(MAX)
SELECT #COUNTRY = #COUNTRY + QUOTENAME(Country)+', '
FROM Customers
GROUP BY Country
SET #COUNTRY= LEFT(#COUNTRY, LEN(#COUNTRY)-1)
SET #COUNTRY2 = REPLACE(#COUNTRY, ',' , '+')
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'SELECT * , '+#COUNTRY2+' AS TOTAL
FROM (SELECT E.EmployeeID, E.LastName,
ISNULL( OD.Quantity, 0)* ISNULL(OD.[UnitPrice],0) QU,
O.ShipCountry AS CO
FROM Orders O JOIN Employees E ON O.EmployeeID = E.EmployeeID
JOIN [dbo].[Order Details] OD ON OD.OrderID = O.OrderID) AS T
PIVOT(SUM(QU) FOR CO IN ('+#COUNTRY+')) AS PVT
ORDER BY 1'
EXEC(#SQL)
I need to change the code in a way that have Null values replaced by 0.
DECLARE #COUNTRY NVARCHAR(MAX) = '' ,
#COUNTRY2 NVARCHAR(MAX);
SELECT #COUNTRY = #COUNTRY + COALESCE(QUOTENAME(Country) + ', ', '')
FROM Customers
WHERE EXISTS ( SELECT *
FROM [Orders] AS [o]
WHERE o.[CustomerID] = Customers.[CustomerID] )
GROUP BY Country;
SET #COUNTRY = LEFT(#COUNTRY, LEN(#COUNTRY) - 1);
SET #COUNTRY2 = REPLACE(#COUNTRY, ',', '+');
DECLARE #SQL NVARCHAR(MAX);
SET #SQL = 'SELECT * , ' + #COUNTRY2 +
' AS TOTAL
FROM (
SELECT oe.EmployeeID, oe.LastName, oe.ShipCountry AS CO,
COALESCE(OD.Quantity * OD.UnitPrice, 0) AS QU
FROM (
SELECT EmployeeID, LastName, ShipCountry
FROM (
SELECT DISTINCT
ShipCountry
FROM Orders
) o ,
Employees
) oe
LEFT JOIN Orders O ON O.EmployeeID = oe.EmployeeID AND
[oe].[ShipCountry] = [O].[ShipCountry]
LEFT JOIN [Order Details] OD ON OD.OrderID = O.OrderID
) AS T
PIVOT(SUM(QU) FOR CO IN (' + #COUNTRY + ')) AS PVT
ORDER BY 1';
EXEC(#SQL);
You need to change the SELECT * to:
SELECT ISNULL(Argentina,0) AS 'Argentina' , INSNULL(Belgium,0) AS 'Belgium' , ....
Ofcourse, you would need to change your dynamic query to reflect the ISNULL functions.
Good Luck

Check for a string in a CLOB

i want to search for a string in a CLOB:
some thing like id_name_2569
i get all my IDs i need like this:
select project_line_id as ID
from tbl1
where art_id in (
select art_id
from tbl2
where type = 3
);
and i search in this table:
A1 is a CLOB field
select * from tbl3 where dbms_lob.instr(A1, ID)>0;
obviously it isnt working i know, is here a way i could do this?
something like this should work:
select tbl3.*
from tbl1
inner join tbl2
on tbl2.art_id = tbl1.art_id
inner join tbl3
on tbl3.a1 like '%' || tbl1.project_line_id || '%'
where tbl2.type = 3;
You can use DBMS_LOB.instr directly as a join condition:
SELECT *
FROM (SELECT project_line_id AS ID
FROM tbl1
WHERE art_id IN (SELECT art_id FROM tbl2 WHERE TYPE = 3)) v
JOIN tbl3 ON dbms_lob.instr(tbl3.a1, v.ID) > 0

EntitySQL 'IN subquery

I have the following T-SQL:
SELECT Cust.[CompanyName]
FROM Customers AS Cust
WHERE
(
Cust.[CompanyName] IN (SELECT CustSQ1.[CompanyName] AS [Customer Company name]
FROM Customers AS CustSQ1
WHERE
(
CustSQ1.Country = 'Argentina' )
) )
How do I do the same in EntitySQL?
I found the solution. Corresponding EntitySQL is:
"SELECT Cust.[CompanyName] FROM (SELECT CustSQ1.[CompanyName] FROM Customers AS CustSQ1 WHERE ( CustSQ1.Country = 'Argentina' )) AS Cust"

Resources