Combining two select statements without on clausule - mysql

I have two tables that are not related at all
First table is called pocetna_baner that stores 3 pictures that are going to be displayed on index page.
pocetna_baner table:
Second table is for blog and I want to take information of 3 blogs ordered by datum desc:
blog table
I tried using UNION, UNION ALL, JOIN without clauses, full outer join, but just cannot get it to work because I never had this situation where there is no on clause
union all with queries that have a different number of columns -> I searched for answers and got to this one which seemed okay but unfortunately couldn't get it to work
This is what I have by now
(SELECT null as blog_id, null as naslov, null as tekst1, null as kategorija, p.ime_slike FROM
pocetna_baner p )
UNION ALL
(SELECT b.blog_id, b.naslov, b.tekst1, b.kategorija ,null as ime_slike
FROM blog b ORDER BY b.datum DESC LIMIT 3 )
And result is this
My expected output is only to take b.blog_id, b.naslov, b.tekst1, b.kategorija FROM blog b ordered by datume desc limit 3 and add column with ime_slike from second table

You can construct the ON clause by creating 1 counter column in each table and matching on them:
select
b.blog_id, b.naslov, b.tekst1, b.kategorija, p.ime_slike
from (
select
blog_id, naslov, tekst1, kategorija,
(#row_number1:=#row_number1 + 1) num
from blog, (select #row_number1:=0) t
order by datum desc limit 3
) b left join (
select ime_slike,
(#row_number2:=#row_number2 + 1) num
from pocetna_baner, (select #row_number2:=0) t
order by id limit 3
) p on p.num = b.num
If you are sure that the ids in the table pocetna_baner have values 1, 2 and 3 then you can simplify to this:
select
b.blog_id, b.naslov, b.tekst1, b.kategorija, p.ime_slike
from (
select
blog_id, naslov, tekst1, kategorija,
(#row_number1:=#row_number1 + 1) num
from blog, (select #row_number1:=0) t
order by datum desc limit 3
) b left join pocetna_baner p
on p.id = b.num

I have just given an example by this code.
Please change as per needs.
SELECT * FROM (
SELECT p.ime_slike,null as blog_id,null as naslov,null as kategorija FROM
pocetna_baner p
UNION ALL
SELECT b.blog_id, b.naslov, b.tekst1, b.kategorija ,null as ime_slike
FROM blog b
ORDER BY datum DESC LIMIT 3 ) AS k

Related

Searching and Sorting Using MySQL Inner Join

I guess I can't explain my problem properly. I want to explain this to you with a picture.
Picture 1
In the first picture you can see the hashtags in the trend section. These hashtags are searched for the highest total and it is checked whether the date has passed. If valid data is available, the first 5 hashtags are taken.
Picture 2
In the second picture, it is checked whether the posts in the hashtag are in the post, if any, the oldest date value is taken, LIMIT is set to 1 and the id value from the oyuncular table is matched with sid. Thus, the name of the person sharing can be accessed.
Picture 3
My English is a little bad, I hope I could explain it properly.
SELECT
social_trend.hashtag,
social_trend.total,
social_trend.tarih,
social_post.sid,
social_post.tarih,
social_post.post,
oyuncular.id,
oyuncular.isim
FROM
social_trend
INNER JOIN
social_post
ON
social_post.post LIKE '%social_trend.hashtag%' ORDER BY social_post.tarih LIMIT 1
INNER JOIN
oyuncular
ON
oyuncular.id = social_post.sid
WHERE
social_trend.tarih > UNIX_TIMESTAMP() ORDER BY social_trend.total DESC LIMIT 5
YOu should use a sibquery
and add a proper join between subqiery and social_trend
(i assumed sing both sid)
SELECT
social_trend.hashtag,
social_trend.total,
social_trend.tarih,
t.sid,
t.tarih,
t.post,
oyuncular.id,
oyuncular.isim
FROM (
select social_post.*
from social_post
INNER JOIN social_trend ON social_post.post LIKE concat('%',social_trend.hashtag,'%' )
ORDER BY social_post.tarih LIMIT 1
) t
INNER JOIN social_trend ON social_trend.hashtag= t.post
INNER JOIN oyuncular ON oyuncular.id = t.sid
WHERE
social_trend.tarih > UNIX_TIMESTAMP() ORDER BY social_trend.total DESC LIMIT 5
but looking to your new explanation and img seems you need
SELECT
t.hashtag,
t.total,
t.tarih_trend,
t.sid,
t.tarih,
t.post,
oyuncular.id,
oyuncular.isim
FROM (
select social_post.sid
, social_post.tarih
, social_post.post
, st.hashtag
, st.total
, st.tarih tarih_trend
from social_post
INNER JOIN (
select * from social_trend
WHERE social_trend.tarih > UNIX_TIMESTAMP()
order by total DESC LIMIT 5
) st ON social_post.post LIKE concat('%',st.hashtag,'%' )
ORDER BY social_post.tarih LIMIT 5
) t
INNER JOIN oyuncular ON oyuncular.id = t.sid

how to enhance efficiency of my query

I have such a query:
SELECT
*,
(
SELECT COUNT(DISTINCT client_id)
FROM 1097_course_students_tbl
WHERE course_cycl_id=id
AND stts_id <> 8
AND client_id IN(SELECT id FROM 1097_clients_tbl WHERE is_removed=0)
) AS cnt
FROM 1097_course_cycle_tbl
WHERE (course_id IN (SELECT id FROM 1097_courses_tbl WHERE is_removed=2))
ORDER BY start_date DESC
I need to make it more efficient because it takes too long
any suggestions ?
thanks
Try the following
SELECT cc.*,IFNULL(q.cnt,0) cnt
FROM 1097_course_cycle_tbl cс
JOIN 1097_courses_tbl с ON c.id=cc.course_id AND c.is_removed=2
LEFT JOIN
(
SELECT cs.course_cycl_id,COUNT(DISTINCT cs.client_id) cnt
FROM 1097_course_students_tbl cs
JOIN 1097_clients_tbl c ON cs.client_id=c.id AND c.is_removed=0
WHERE cs.stts_id<>8
GROUP BY cs.course_cycl_id
) q
ON q.course_cycl_id=cс.id
ORDER BY cc.start_date DESC
I think id in 1097_courses_tbl and 1097_clients_tbl is primary key.
Therefore I replaced IN into JOIN.
And I converted the subquery from SELECT block wich executed for each rows into the subquery with GROUP BY which using in LEFT JOIN. Here it'll execute only one time and return all the necessary information.

How to make sql query?

Here is the structure of table Likes:
id(int 11)
idn(varchar 10)
type (enum ('up','down'))
Here is the structure of table News:
id(int 11)
idn(varchar 10)
header (varchar 100)
date(datetime)
To show news, I use sql query:
SELECT header FROM News n left join Likes l on l.idn=n.idn ORDER by n.date
But now I want to select headers news From table News with order by desc count rows in table Likes with type = up.
How can I do this?
Here is a query to get top liked headers for each day. If you need TOP for all dates remove n.date from the ORDER BY:
SELECT header FROM News as n
LEFT JOIN
(
Select idn,Count(*) as UpLikes FROM Likes WHERE type='up' GROUP BY idn
) as l
ON l.idn=n.idn
ORDER BY n.date,l.UpLikes DESC
Why don't you use this:
SELECT id, idn, header, LikeCount
FROM
(
SELECT id, idn, header, (SELECT COUNT(1) FROM [Likes]) AS [LikeCount]
FROM [News]
)
ORDER By [LikeCount]
SELECT n.header, COUNT(i.`id`) as like_count
FROM Likes l LEFT JOIN News n ON n.idn = l.idn
WHERE l.`type` = 'up'
ORDER BY like_count DESC

Inner join to select MAX value from the SUM of Rows

http://sqlfiddle.com/#!2/1a2df
I am trying to select a column "photo_name" by counting the MAX value of SUM(valid)
the preferred results is "test5.jpg" but after hours of trying, I still can't figure it out ,
below is my previous approach, but it doesn't work
SELECT photo_name FROM
(
SELECT a.*
FROM test a
INNER JOIN
(
SELECT *, SUM(valid) v
FROM test
WHERE page_id = 3 AND `valid` = 1
) b ON MAX(b.v)
)c
Please help,
Something like this should work. It sums the valid column for each photo, orders high-to-low for the sum, then limits results to the top row:
SELECT photo_name, SUM(valid) AS sum_valid
FROM test
GROUP BY photo_name
ORDER BY sum_valid DESC
LIMIT 1

remove only duplicates ids

I got 2 tables: job and job_working_time
job: id (Increment, Index, Unique)
job_working_time: job_id(allow multiple), property_working_time
This SQL query returns the ids with multiple values or duplicates. It helps, but it doesn't fix my problem:
SELECT a.id AS id, count( b.job_id ) AS cnt, b.property_working_time AS value
FROM job a
INNER JOIN job_working_time b ON a.id = b.job_id
GROUP BY b.job_id
HAVING cnt >1
I want to remove duplicates, only for ids with duplicates, e.g: l = leave, r = remove
1 - 1 (l)
1 - 1 (r)
1 - 2 (l)
1 - 3 (l)
1 - 1 (r)
2 - 1 (l)
2 - 1 (r)
2 - 2 (l)
Thanks in advance
[Later edit]
One thing you should consider:
Anyway, when I want to delete the ID, will remove all values for it. So, the idea is to keep all the values for that id, so later I can add without duplicates. That's why it's so important to retrieve, both the id and the value, but not duplicate content. The SQL should return all the (l) values from the above e.g. list.
Since your example looks like you don't want any row be same
DISTINCT will work for you
it select completely diffirent rows
SELECT DISTINCT a.id AS id, count( b.job_id ) AS cnt, b.property_working_time AS value
FROM job a
INNER JOIN job_working_time b ON a.id = b.job_id
GROUP BY b.job_id
HAVING cnt >1
Edit:
Example added
https://data.stackexchange.com/stackoverflow/q/119267/
First/ simple Query:
SELECT id, field, count(*) c from ... group by field having c >1
Second Query, modifed for get IDs to delete:
SELECT instr(s,mid(s,',')+1) from (
SELECT group_concat(id) s, count(*) c from ... group by field having c >1)z
and the end:
Delete FROM ... WHERE id in ( ...)
looks ugly, but fast (Mid function performance is faster than not in (...)).