Selecting data from 3 tables with limit - php

I have 3 tables ppc_offers, survery_offers,find_offers ( from admin section, i enter data into these tables)
Now on front end, i want to display latest 3 offers from these tables.
i.e. latest 3 will come, they can be from single table or multiple tables... it just has condition "latest 3"
How can i do this?
Laravel provides any way to do this?
or do i need to have any master table?
or can you suggest me regular SQL query for this?
Please help.
Thanks.
PPC Table:
-------------------------
id | integer
title | varchar
url | varchar
description | varchar
created_at | timestamp
updated_at | timestamp
--------------------------
survey Table:
-------------------------
id | integer
title | varchar
created_at | timestamp
updated_at | timestamp
--------------------------
find code Table:
-------------------------
id | integer
title | varchar
url | varchar
description | varchar
code | varchar
created_at | timestamp
updated_at | timestamp
--------------------------

Make 3 queries union them with the same names for columns
select * from
(
(query1 order by id desc limit 3) x
union
(query2 order by id desc limit 3) y
union
(query3 order by id desc limit 3) z
(

As a recommendation, it might make more sense to include all 3 of these offers in one table, and use an "offer_type" id to distinguish them from each other, instead of using 3 different tables. It might simplify your code.
I believe this may work with your current setup:
$ppc = DB::table('ppc_offers')
->select('title', 'url', 'description', 'NULL as code', 'updated_at');
$survey = DB::table('survey_offers')
->select('title', 'NULL as url', 'NULL as description', 'NULL as code', 'updated_at');
$find = DB::table('find_offers')
->select('title', 'url', 'description', 'code', 'updated_at');
return $ppc->unionAll($survey)->unionAll($find)
->orderBy('updated_at', 'desc')
->take(3)
->get();

Related

MySQL Specific condition for each row in same query +PHP

Please consider my tables
store - table with information of all my stores
zone - An alias table with zone_id and the name of the zone.
store_zone - Table that contains the information when a store was changed to a different zone.
cashdesk - table with local_id that contains information about the
income for each day and each store
store_zone table:
+----+----------+---------+-------------+
| id | store_id | zone_id | modified_at |
+----+----------+---------+-------------+
| 1 | 1 | 2 | 2019-01-01 |
| 2 | 1 | 1 | 2019-01-04 |
| 3 | 2 | 4 | 2019-01-03 |
+----+----------+---------+-------------+
store_id is the foreign key for my local table id
store table also contains a fk for zone_id
zone_id is the foreign key for my zone table id
Now consider my problem:
I need to select all stores
get the sum(income) per row (stores)
filter by zone
consider only incomes that correspond to the local_zone table between
dates. (if I select the whole month and a zone was changed the day
15.. I only care about the 15 first days). I can use php to help build it.
something like:
$zone_modified_dates = //result of
"SELECT modified_at
FROM store_zone
WHERE zone_id = 1 AND store_id = 1"
$zone_modified_dates = '2019-01-04'
SELECT sum(income) from cashdesk c
inner join store s ON s.id = c.store_id
inner join store_zone sz ON (sz.store_id = s.id AND sz.zone_id = z.id
WHERE zone_id = 1
AND cashdesk created_at >= '2019-01-01'
AND cashdesk created_at >= '2019-01-10'
AND //IF ZONE WAS CHANGED IN THIS CREATED_AT BETWEEN DATES ONLY CONSIDER THE DAYS THAT THE SPECIFIC ROW STORE WAS CONSIDERED ZONE 1
GROUP BY s.id
Thanks in advance.
#edited for better explanation of the problem.

laravel table structure showing the most liked articles and less views

users can add articles and other users can like or dislike I need most liked with the less view
example :
article (A) has 500 views and 10 like - article (B) has 50 views and 10 likes
the order will be (B) than (A)
This is my database structure and I join them together:
articles table:
id | user_id | title | description | views | created_at | updated_at
likes table:
id | user_id | article_id | like_type | created_at | updated_at
query to get likes count :
Article::leftJoin('likes', 'likes.article_id', '=', 'articles.id')
->select('articles.*', DB::Raw('SUM( 2 * likes.like_type -1) as likes_count'))
->groupBy('articles.
->get();
how can i order ?
You can order by multiple columns in laravel by chaining orderBy.
In your case for example you will want to first order by "likes_count" descending (=biggest first) and then by views ascending (= smallest first, this is the default value).
So you will do:
return Article::select('title', DB::Raw('SUM(2*likes.like_type-1) as likes_count'))
->leftJoin('likes', 'likes.article_id', '=', 'articles.id')
->groupBy('articles.id')
->orderBy('likes_count', 'DESC')->orderBy('views')
->get();

Facing difficulties to write a sql query in laravel

We have three tables users,answers and stretches. When someone login to our system we stored user_id,created_at and updated_at in stretches table and when he/she logout updated deleted at in the same row.
Session time 30 minutes.
users table
id
f_name
l_name
email
answers table
id
user_id
body
created_at
updated_at
stretches table
id
user_id
created_at
updated_at
deleted_at
Now i want to get only those rows from the stretches table where an answer has been given. I wrote this query but it takes to much time but did not return accurate data.
$query = "select count(a.id), a.user_id
from answers a
where a.created_at in
(select s.created_at
from stretches s
where s.created_at >= a.created_at
) group by a.user_id";
$results = DB::select(DB::raw($query));
I'd be curious to hear how some of you write this query.
Answers table
id | body | user_id | created_at | updated_at
10 | text | 10 | 2015-10-10 0:0:0 | 2015-10-10 0:0:0
Stretches Table
id | user_id | created_at | updated_at | deleted_at
1 | 10 | 2015-10-00 0:0:0 | 2015-10-10 0:0:0 | 2015-10-20 0:0:0
Now i want to get those rows from stretches table where an answer has been given.
Query results should be:
id | user_id | created_at | updated_at | deleted_at
1 | 10 | 2015-10-10 0:0:0 |2015-10-10 0:0:0 | 2015-10-10 0:0:0
If I correctly understood you. SQL query below will return only those records from table Stretches where answer was given to user. Use operator JOIN, it will do filter work for you.
SELECT S.user_id, COUNT(*) as answers_count FROM Stretches AS S
JOIN Answers AS A ON S.user_id = A.user_id
GROUP BY S.user_id
This should do the job
SELECT DISTINCT Stretches.* FROM Stretches
JOIN Answers ON Stretches.user_id = Answers.user_id
GROUP BY Stretches.user_id

Know last X field value

I have a database with this table
+------+---------------------+-------------+
| id | key | value |
+------+---------------------+-------------+
| 152 | incidencia_0_fecha | 20150306 |
| 158 | incidencia_1_fecha | 20150307 |
| 234 | incidencia_2_fecha | 20150309 |
| . | ...... | ........ |
| n | incidencia_N_fecha | date_value |
+------+---------------------+-------------+
And I want to know what is the last key (N its dinamic and i don't know his last value). In this table the last must be incidencia_2_fecha.
How can i do it?
Thanks
You can easily get the number in the string using two REPLACES.
SELECT MAX(
REPLACE(REPLACE(`key`, 'incidencia_', ''), '_fecha', '')
)
FROM mytable
If the values in the id column are strictly increasing, you can do this:
SELECT key FROM your_table WHERE id = (SELECT MAX(id) FROM your_table);
EDIT 1:
If the table is quite large, you should make sure that there's an index on the id column. Otherwise the query could take a long time to run.
EDIT 2:
Another option, if the value column contains the date at the time the record was inserted (and is indexed), would be to do the above query, but replace id with value, i.e.
SELECT key FROM your_table WHERE value = (SELECT MAX(value) FROM your_table);
First fetch record in desc
SELECT key from tbl_name ORDER BY id DESC LIMIT 0,1

MySQL ORDER BY 'ENUM' type value

I'm having a table:
ID TYPE VALUE
1 phone 12345
2 fax 98753
3 address etc
...
the TYPE col is defined as ENUM with values: 'phone','fax','address'.
Now my query is:
$q = mysql_query(SELECT * FROM tbl ORDER BY id);
while(row = mysql_fetch_array($q)){
echo $row['type'] . "--->" . $row['value'];
}
The output is ordered by id, first line is phone, then it's fax and then it's address.
But I want the output be order by:
1- All address
2- All Phone
3- All fax
How I could achieve this?
Thanks for your help :-)
Try this query -
SELECT * FROM tbl
ORDER BY
CASE type
WHEN 'address' THEN 1
WHEN 'phone' THEN 2
WHEN 'fax' THEN 3
ELSE 4
END
Full example:
CREATE TABLE tbl (
id int(11) DEFAULT NULL,
type enum ('phone', 'fax', 'address') DEFAULT NULL,
value int(11) DEFAULT NULL
);
INSERT INTO test.tbl(id, type, value) VALUES
(1, 'phone', 11),
(2, 'fax', 22),
(3, 'address', 33),
(4, 'fax', 44),
(5, 'address', 55);
SELECT * FROM tbl
ORDER BY
CASE type
WHEN 'address' THEN 1
WHEN 'phone' THEN 2
WHEN 'fax' THEN 3
ELSE 4
END;
+------+---------+-------+
| id | type | value |
+------+---------+-------+
| 3 | address | 33 |
| 5 | address | 55 |
| 1 | phone | 11 |
| 2 | fax | 22 |
| 4 | fax | 44 |
+------+---------+-------+
SELECT A.*,
case ID
when 3 then 1
when 2 then 3
when 1 then 2
else 4 end as myorder
FROM tbl A
ORDER BY myOrder
Alternatively update the enum to list the Number first on the type field such as 01.Address, 02.Phone, 03.Fax.. then your order by type instead of ID. The 2nd approach makes it pretty easy to add up to 99 types without having to change code (just data) if you add another type later using the first approach, you have to edit the SQL...
The first approach uses a case statement to generate a calculated column at run time. This new column contains the correct order by substituting the IDs for the order you want (it doesn't change the IDs, it simply defines them in the order you want) and then orders by this new calculated column.
$q = mysql_query(SELECT A.*, case ID when 3 then 1 when 2 then 3 when 1 then 2 else 4 end as myorder FROM tbl A ORDER BY myOrder);
The second approach involves changing the data in the enum such that it is preceeded by a number which defines the sort you want. Thus if you change the SQL in your sort to sort by Type instead of ID, it would then work.
$q = mysql_query(SELECT * FROM tbl ORDER BY Type);

Categories