MYSQL QUERY : Select 1 rows photo from table for each album - mysql

I have a table with records and it has a table called gallery. I have inserted too many photo and I want to select only 2 random photo from each gallery.
here my structured
CREATE TABLE IF NOT EXISTS `gallery` (
`gallery_id` int(11) NOT NULL,
`gallery_name` varchar(100) NOT NULL,
`gallery_name_seo` varchar(120) NOT NULL,
`gallery_client` varchar(100) NOT NULL,
`gallery_date` date NOT NULL,
`gallery_type` int(2) NOT NULL,
`gallery_desc` text,
`gallery_publish` char(1) NOT NULL DEFAULT 'N' COMMENT 'Y = Yes & N = No',
`gallery_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`deleted` int(11) NOT NULL DEFAULT '0'
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
and here another table
CREATE TABLE IF NOT EXISTS `gallery_photo` (
`id` int(10) NOT NULL,
`id_gallery` int(10) NOT NULL,
`file_name` varchar(255) NOT NULL,
`file_added` date NOT NULL,
`deleted` smallint(6) NOT NULL DEFAULT '0'
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=latin1;
acctually there many example here but i hard to understand,
how to create query from my problem.?
thanks

The following query would give you 1 random photo per id_gallery:
SELECT *
FROM (SELECT * FROM `gallery_photo` ORDER BY RAND()) as `rand_photos`
GROUP BY rand_photos.id_gallery
You could UNION it with itself to get 2 random photos for each gallery:
SELECT *
FROM (SELECT * FROM `gallery_photo` ORDER BY RAND()) as `rand_photo1`
GROUP BY rand_photo1.id_gallery
UNION
SELECT *
FROM (SELECT * FROM `gallery_photo` ORDER BY RAND()) as `rand_photo2`
GROUP BY rand_photo2.id_gallery
ORDER BY id_gallery

Related

SQL with subquery WHERE condition is empty

I am hoping someone can advise on what is wrong.
SELECT sms.id FROM sms INNER JOIN screens ON sms.screen_id = screens.id WHERE screens.experience_id = '108';
AND
SELECT id FROM sms
WHERE screen_id IN (SELECT id FROM screens WHERE experience_id = 108 )
... returns an empty row, but there are rows that should be returned.
To clarify...
SELECT id FROM sms
... returns all rows in SMS
SELECT id FROM sms
WHERE screen_id IN (SELECT id FROM screens)
... returns all rows in SMS and
SELECT id FROM screens WHERE experience_id = 108
... returns all rows from screens with that id.
SQL to make the tables...
CREATE TABLE IF NOT EXISTS `screens` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`device_id` int(11) NOT NULL,
`type` varchar(32) NOT NULL,
`description` text NOT NULL,
`position` int(11) NOT NULL,
`experience_id` int(11) NOT NULL,
`image` varchar(512) NOT NULL,
`url` varchar(512) NOT NULL,
`persona_id` int(11) NOT NULL,
`socialPost` text NOT NULL,
`socialLinkHeadline` varchar(512) NOT NULL,
`socialLinkDescription` text NOT NULL,
`socialLink` varchar(512) NOT NULL,
`socialAction` varchar(64) NOT NULL,
`bgcolor` varchar(16) NOT NULL DEFAULT '#fff',
`created` datetime NOT NULL,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=472 ;
CREATE TABLE IF NOT EXISTS `sms` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`source` varchar(16) NOT NULL,
`content` text NOT NULL,
`position` int(11) NOT NULL,
`screen_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=20 ;
A GIF of me running these queries to verify is here: https://ibb.co/gzPFsd
I am at a loss and can see that people can't replicate, thanks!
I don't get what's wrong in your query but you can do that using join as well.
SELECT sms.id FROM sms INNER JOIN screens ON sms.screen_id = screens.id WHERE screens.experience_id = '108';
Your query works fine , here's the proof.
DROP TABLE IF EXISTS SMS,SCREENS;
CREATE TABLE SMS(ID INT, SCREEN_ID INT);
CREATE TABLE SCREENS(ID INT, EXPERIENCE_ID INT);
INSERT INTO SMS VALUES (1,1),(2,2);
INSERT INTO SCREENS VALUES(1,108),(2,100);
SELECT id FROM sms
WHERE screen_id IN (SELECT id FROM screens WHERE experience_id = 108 );
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
Assuming that my data model and yours are the same.

Mysql : select aggregated values in between dates

I've got mysql query (generated by zf2), it looks like
SELECT `subt`.`from` AS `from`, SUM(ordered) AS `sum_ordered`,
SUM(income) AS `sum_income`, SUM(sales_by_payment) AS
`sum_sales_by_payment`
FROM (
SELECT `w`.`brand` AS `brand`, `w`.`article` AS `article`,
`w`.`subject` AS `subject`, `w`.`size` AS `size`, `w`.`from` AS
`from`, (
SELECT SUM(IFNULL(income,0)) AS `income`) AS `income`, (
SELECT SUM(IFNULL(income_sum_price,0)) AS `income_sum_price`) AS
`income_sum_price`, (
SELECT SUM(IFNULL(ordered,0)) AS `ordered`) AS `ordered`, (
SELECT SUM(IFNULL(ordered_sum_price,0)) AS `ordered_sum_price`) AS
`ordered_sum_price`, (
SELECT SUM(IFNULL(ordered_max_by_day,0)) AS `ordered_max_by_day`) AS
`ordered_max_by_day`, (
SELECT SUM(IFNULL(return_before_payment,0)) AS
`return_before_payment`) AS `return_before_payment`, (
SELECT SUM(IFNULL(return_before_payment_sum_price,0)) AS
`return_before_payment_sum_price`) AS
`return_before_payment_sum_price`, (
SELECT SUM(IFNULL(sales_by_payment,0)) AS `sales_by_payment`) AS
`sales_by_payment`, (
SELECT SUM(IFNULL(sales_by_payment_sum_price,0)) AS
`sales_by_payment_sum_price`) AS `sales_by_payment_sum_price`, (
SELECT SUM(IFNULL(`return`,0)) AS ```return```) AS `return`, (
SELECT SUM(IFNULL(`return_sum_price`,0)) AS ```return_sum_price```)
AS `return_sum_price`, (
SELECT SUM(IFNULL(`stock`,0)) AS ```stock```) AS `stock`, (
SELECT SUM(IF (sales_by_payment IS NOT NULL,
sales_by_payment_sum_price / sales_by_payment, NULL)) AS
`sale_price`) AS `sale_price`, (
SELECT SUM(income_sum_price * 0.62) AS `our_percent`) AS
`our_percent`, (
SELECT SUM(IFNULL(income_sum_price,0) * 0.25) AS
`cost_price_income`) AS `cost_price_select`, (
SELECT SUM(IFNULL(sales_by_payment_sum_price,0) -
(IFNULL(income_sum_price,0) * 0.25)) AS `profit`) AS `profit`, (
SELECT SUM(IF(income IS NOT NULL, (sales_by_payment / income) *
100, 0)) AS `sales_from_income`) AS `sales_from_income`, (
SELECT (SUM(sales_by_payment) / SUM(return_before_payment)) * 100 AS
`returns_buyout`) AS `returns_buyout`, (
SELECT SUM(return_before_payment) / SUM(ordered) * 100 AS `returns`) AS
`returns`, (
SELECT SUM(sales_by_payment) / SUM(ordered) * 100 AS `buyout`) AS
`buyout`, (
SELECT SUM(IFNULL(income,0) - IFNULL(sales_by_payment,0) +
IFNULL(`return`,0)) AS `total`) AS `total`, (
SELECT (SUM(IFNULL(income,0)) - SUM(IFNULL(stock,0)) -
SUM(IFNULL(`sales_by_payment`,0)) + SUM(IFNULL(`return`,0))) AS
`in_the_way`) AS `in_the_way`
FROM `wildberries` AS `w`
WHERE `from` >= '2016-02-01' AND `end` <= '2017-05-04'
GROUP BY `article`
ORDER BY `article` DESC
LIMIT 20 OFFSET 0) AS `subt`
GROUP BY DAY(`from`)
ORDER BY `from` ASC
If dates range are between one year, all works fine. But if i use different years, it returns only one row.
Could anyone give me advice - why is it happen and how should i modify query?
Table scheme is
CREATE TABLE `wildberries` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`brand` VARCHAR(50) NULL DEFAULT NULL,
`subject` VARCHAR(50) NULL DEFAULT NULL,
`article` VARCHAR(50) NULL DEFAULT NULL,
`size` VARCHAR(50) NULL DEFAULT NULL,
`income` VARCHAR(50) NULL DEFAULT NULL,
`income_sum_price` VARCHAR(50) NULL DEFAULT NULL,
`ordered` VARCHAR(50) NULL DEFAULT NULL,
`ordered_sum_price` VARCHAR(50) NULL DEFAULT NULL,
`ordered_max_by_day` VARCHAR(50) NULL DEFAULT NULL,
`return_before_payment` VARCHAR(50) NULL DEFAULT NULL,
`return_before_payment_sum_price` VARCHAR(50) NULL DEFAULT NULL,
`sales_by_payment` VARCHAR(50) NULL DEFAULT NULL,
`sales_by_payment_sum_price` VARCHAR(50) NULL DEFAULT NULL,
`return` VARCHAR(50) NULL DEFAULT NULL,
`return_sum_price` VARCHAR(50) NULL DEFAULT NULL,
`stock` VARCHAR(50) NULL DEFAULT NULL,
`source_file` VARCHAR(50) NULL DEFAULT NULL,
`from` DATE NULL DEFAULT NULL,
`end` DATE NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `article` (`article`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
In your subquery you group by column article, but you select column from. You don't tell the DBMS which of the article's froms you want to see. This is invalid according to the SQL standard, but MySQL lets this slip and gives you one of the article's froms arbitrarily chosen.
So for the first 20 articles you select rather random dates.
In your main query you group by these dates' days parts. This can result in 1 to 20 rows and is based on coincidence (i.e. how the records happen to be stored on disk at that moment and how the DBMS retrieves them).

MySQL Order by subquery column

I have problem with sql query. The idea is to select all loans that are after payment (status 1/2/3) between 8 and 21 days with calculated value from payment_day til now.
I have already done some query but can't use columns days_after_payment and days_after_part_payment in WHERE section. I would like to have one column like days_after_payment based on loan type.
SELECT l.*,
(SELECT SUM(`value`) FROM `loan_part` WHERE `loan_id` = l.id AND `paid`=0) AS left_to_pay,
-(DATEDIFF((SELECT date FROM `loan_part` WHERE `loan_id` = l.id AND `paid`=0 AND `date`<CURDATE() ORDER BY `date` LIMIT 1), NOW())) AS days_after_part_payment,
-(DATEDIFF(l.payment_date, NOW())) AS days_after_payment
FROM loan l
WHERE (l.type=1 or l.type=2) AND (l.status=1 OR l.status=2 OR l.status=3)
GROUP BY l.client_id
ORDER BY
CASE l.type
WHEN 1 THEN days_after_payment
WHEN 2 THEN days_after_part_payment
ELSE 1 END
ASC
CREATE TABLE IF NOT EXISTS `loan` (
`id` int(11) NOT NULL,
`value` int(11) NOT NULL,
`client_id` int(11) NOT NULL,
`status` int(11) NOT NULL,
`type` int(11) NOT NULL,
`payment_date` date DEFAULT NULL
) ENGINE=MyISAM AUTO_INCREMENT=2068 DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `loan_part` (
`id` int(10) unsigned NOT NULL,
`loan_id` int(11) NOT NULL,
`value` float NOT NULL,
`date` date DEFAULT NULL,
`paid` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=MyISAM AUTO_INCREMENT=1751 DEFAULT CHARSET=utf8;
Update1 : I had to cut unnecessary columns and rewrite it into English from my native language.
ORDER BY 7
"7" means the 7th field in the SELECT. That works for GROUP BY also. I had to see the table definition to count how many in l.*.
How come id is not declared AUTO_INCREMENT?

MySQL Need advice on Query

I want to fetch latest 3 news from each news type.
CREATE TABLE IF NOT EXISTS `news` (
`news_id` int(8) NOT NULL AUTO_INCREMENT,
`news_heading` tinytext NOT NULL,
`news_description` text NOT NULL,
`news_date` date DEFAULT NOT NULL,
`news_type` tinyint(1) NOT NULL COMMENT '0- PEP|1 - MEDIA|2 - CONSULTING',
`created_date` datetime NOT NULL,
`modified_date` datetime NULL,
`display` tinyint(1) NOT NULL COMMENT '0- ON | 1 -OFF',
PRIMARY KEY (`news_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
Below Query will give me only 1 latest news from all type. Suggest me how we can achieve for top 3 from each type
SELECT * FROM (
SELECT * FROM `news`
ORDER BY `created_date` DESC
) AS TBL
GROUP BY `news_type`
Try this:
SELECT news_id, news_heading, news_description, news_date,
news_type, created_date, modified_date, display
FROM (SELECT news_id, news_heading, news_description, news_date,
news_type, created_date, modified_date, display,
IF(#news_type = #news_type:=news_type, #id:=#id+1, #id:=1) AS id
FROM news, (SELECT #id:=1, #news_type:=0) A
ORDER BY news_type, created_date DESC
) AS A
WHERE id <= 3;

MySQL: Find "last modified" date from two tables

I have two MySQL tables: tech_requests and comments. I want to display each tech_request one time in a list ordered by the "last modified" date, whether that be the date of the tech_request creation or the latest comment tied to that tech_request. I was trying to use UNION but I got stuck. Any ideas would be much appreciated. Here are the tables:
CREATE TABLE `tech_requests` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`staff_member_id` int(3) NOT NULL,
`date_time` datetime NOT NULL,
`request` text NOT NULL,
`building_id` int(2) NOT NULL,
`technician_id` int(2) DEFAULT NULL,
`completed` tinyint(1) NOT NULL,
`subject` varchar(30) NOT NULL DEFAULT '',
`category_id` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=203 DEFAULT CHARSET=utf8;
CREATE TABLE `comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tech_request_id` int(11) NOT NULL,
`technician_id` int(2) NOT NULL,
`date_time` datetime NOT NULL,
`comment` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=234 DEFAULT CHARSET=utf8;
Are you looking for something like this?
SELECT r.id, r.staff_member_id, ...,
GREATEST(r.date_time, COALESCE(c.date_time, 0)) last_modified
FROM tech_requests r LEFT JOIN
(
SELECT tech_request_id, MAX(date_time) date_time
FROM comments c
GROUP BY tech_request_id
) c
ON r.id = c.tech_request_id
ORDER BY last_modified
Here is SQLFiddle demo