Mysql case when getting another table - mysql

I have got two tables one is log details and another is user name list.
I can get with "INNER JOIN user_tbl ON log_user_id=user_id" but also I have got a super user id is exception and this exception user isn't in the user table. I am using this user at the back ground the relation with database is level of this user like as 9999.
How can I show the super user as a name like as "Supervisory"?
Example sql:
Table structures are:
CREATE TABLE `user_list_tb` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(40) COLLATE utf8_turkish_ci NOT NULL,
`user_pwd` varchar(40) COLLATE utf8_turkish_ci NOT NULL,
`user_level` int(11) NOT NULL DEFAULT '0',
`user_owner_id` int(10) unsigned NOT NULL,
`user_datetime` datetime NOT NULL,
`user_change_pwd` tinyint(1) DEFAULT NULL,
`user_pwd_try` int(3) unsigned DEFAULT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `user_name_UNIQUE` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci;
CREATE TABLE `log_system_tb` (
`log_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`log_act_name` varchar(10) COLLATE utf8_turkish_ci NOT NULL,
`log_user_id` int(10) unsigned NOT NULL,
`log_datetime` datetime NOT NULL,
`log_message` varchar(256) COLLATE utf8_turkish_ci DEFAULT NULL,
PRIMARY KEY (`log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=49720 DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci;
SELECT
log_id,
log_act_name,
log_user_id,
user_name,
log_datetime,
log_message
from log_system_tb
JOIN user_list_tb
ON (log_user_id=user_id)
where log_datetime>="2016-04-01 00:00:00"
and
log_datetime<="2016-04-14 00:00:00"
order by log_id desc limit 1000;
Best regards
Mehmet

You need to use a left join because there will not be a row in the user_list that corresponds to the supervisor's logged events. Also please see the case statement below.
SELECT
log_id,
log_act_name,
log_user_id,
(case when user_id=9999 then 'Supervisory' ELSE user_name END),
log_datetime,
log_message
from log_system_tb
LEFT JOIN user_list_tb
ON (log_user_id=user_id)
where log_datetime>="2016-04-01 00:00:00"
and
log_datetime<="2016-04-14 00:00:00"
order by log_id desc limit 1000;

You can do it like this:
(case when user_id=9999 then 'Supervisory' END)

Related

How to store translates in MySQL to use join?

I have a table that contains all translations of words:
CREATE TABLE `localtexts` (
`Id` int(11) NOT NULL,
`Lang` char(2) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'pe',
`Text` varchar(300) DEFAULT NULL,
`ShortText` varchar(100) NOT NULL,
`DbVersion` timestamp NOT NULL DEFAULT current_timestamp(),
`Status` int(11) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
As example there is a table that refers to localtexts:
CREATE TABLE `composes` (
`Status` int(11) NOT NULL DEFAULT 1,
`Id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The table above has foreign key Id to localtexts.Id. And when I need to get word on English I do:
SELECT localtexts.text,
composes.status
FROM composes
LEFT JOIN localtexts ON composes.Id = localtexts.Id
WHERE localtexts.Lang = 'en'.
I'm concerned in performance this decision when there are a lot of tables for join with localtexts.
You might find that adding the following index to the localtexts table would speed up the query:
CREATE INDEX idx ON localtexts (Lang, id, text);
This index covers the WHERE clause, join, and SELECT.

MySql Using filesort when i using a group by

I have a little problem with optimizing a query, I have 2 tables, one which records the participation (participation) in a quiz, and the other which records the answer to each question (participation_rep), participation is linked to the campaign table.
SELECT count(DISTINCT p.id) as number_of_participation
FROM participation_rep prep
INNER JOIN participation p
ON p.id = prep.id_participation
AND p.trash <> 1
WHERE prep.id_question IN (780,787,794,801,809)
AND prep.trash <> 1
GROUP BY pp.id_campaign
Explain of the query
And the problem is that this request is very heavy to execute when there is a lot of data which is concerned by the request and I do not know how to optimize it.
This query take 30-50ms to execute.
Structure of table participation :
CREATE TABLE IF NOT EXISTS `participation` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_campagne` int(11) NOT NULL,
`id_identifiant` int(11) DEFAULT NULL,
`firstname` varchar(255) DEFAULT NULL,
`surname` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`date_p` date NOT NULL,
`hour_p` time NOT NULL,
`comment` text,
`trash` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Structure of table participation_rep :
CREATE TABLE IF NOT EXISTS `participation_rep` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_participation` int(11) NOT NULL,
`id_question` int(11) NOT NULL,
`id_rep` int(11) NOT NULL,
`trash` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id_participation` (`id_participation`,`id_question`,`id_reponse`),
KEY `id_question` (`id_question`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Message service query on Mysql

I have a problem which I've trying to solve for days and couldnt figure this out. Please Please help me if you have any idea or tip anything .
Im trying to make a messaging service on my website. There is a product and users will able to message under it.There will be 2 users at max. Not like a comment line. Here is the database schemes I made .
ps:
$user1 ; a person who login the website,
$user2 ; the person who posted the product
$id ; the id of posted product
>CREATE TABLE `conversation`
c_id int(11)
product_id int(11) DEFAULT NULL
user_one int(11) NOT NULL
user_two int(11) NOT NULL
time int(11) DEFAULT NULL
PRIMARY KEY (`c_id`),
KEY `user_one`(`user_one`),
KEY `user_two` (`user_two`),
KEY `product_id`(`product_id`)
CREATE TABLE `conversation_reply`
`cr_id` int(11) NOT NULL AUTO_INCREMENT,
`reply` text COLLATE utf8_unicode_ci,
`user_id_fk` int(11) NOT NULL,
`time` int(11) DEFAULT NULL
`c_id_fk` int(11) NOT NULL,
PRIMARY KEY (`cr_id`),
KEY `user_id_fk` (`user_id_fk`)
KEY `c_id_fk`(`c_id_fk`)
'CREATE TABLE `post`
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
`subject` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`user_post` varchar(300) COLLATE utf8_unicode_ci NOT NULL
`time_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`type` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
`product_img` longtext COLLATE utf8_unicode_ci NOT NULL,PRIMARY KEY (`id`)
post's id referenced to product_id in conversation table
user_id_fk referenced to id in member's table
c_id referenced to as c_id_fk in conversation_reply table
Here is the query I'm trying to do.However It doesn't properly work.
SELECT U.id,C.c_id,U.username,R.reply
FROM member U,conversation C, conversation_reply R,post P
WHERE
CASE
WHEN C.user_one = '$user1' THEN C.user_two = U.id
WHEN C.user_two = '$user2' THEN C.user_one= U.id
END
AND
C.c_id=R.c_id_fk
AND
(C.user_one ='$user1' OR C.user_two ='$user2')
AND C.product_id='$id' ORDER BY C.c_id DESC

MySQL Left join take too long for huge data

I have two tables .Property tables and it related photo.One property may have many photo but I want only one any of it related photo, When I use left join MySQL query it become too slow.
Here is my query
SELECT `sp_property`.`id` as propertyid, `sp_property`.`property_name`, `sp_property`.`property_price`, `sp_property`.`adv_type`, `sp_property`.`usd`, `images`.`filepath_name`
FROM (`sp_property`)
LEFT JOIN (select id, Max(property_id) as pid,filepath_name
from sp_property_images
group by property_id) `images`
ON `images`.`pid` = `sp_property`.`id`
WHERE `sp_property`.`published` = 'yes'
GROUP BY `propertyid`
ORDER BY `sp_property`.`feature_listing` desc, `submit_date` desc
LIMIT 1,20
CREATE TABLE IF NOT EXISTS `sp_property_images` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`property_id` varchar(100) NOT NULL,
`filepath_name` text,
`label_name` varchar(45) DEFAULT NULL,
`primary` char(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `property_id` (`property_id`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=12941 ;
CREATE TABLE IF NOT EXISTS `sp_property` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`propertytype` varchar(50) NOT NULL,
`adv_type` varchar(45) NOT NULL,
`property_name` text,
`division` varchar(45) NOT NULL,
`township` varchar(45) NOT NULL,
`property_price` decimal(20,2) unsigned DEFAULT NULL,
`price_type` varchar(45) NOT NULL,
`availability` varchar(100) DEFAULT NULL,
`property_address` text,
`p_dimension_length` varchar(45) NOT NULL,
`p_dimension_width` varchar(45) NOT NULL,
`p_dimension_sqft` varchar(45) NOT NULL,
`p_dimension_acre` varchar(45) NOT NULL,
`floor` varchar(45) NOT NULL,
`phone` varchar(100) DEFAULT NULL,
`aircorn` varchar(45) NOT NULL,
`ownership` varchar(45) NOT NULL,
`bedroom` varchar(45) NOT NULL,
`bathroom` varchar(45) NOT NULL,
`special_feature` text,
`amentites` text,
`property_detail` text,
`submit_date` datetime DEFAULT NULL,
`published` varchar(45) NOT NULL,
`published_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`agent_id` varchar(45) NOT NULL,
`source` varchar(45) NOT NULL,
`contact_name` varchar(100) NOT NULL,
`contact_no` varchar(100) NOT NULL,
`contact_address` text NOT NULL,
`contact_email` varchar(100) NOT NULL,
`unit_type` varchar(100) DEFAULT NULL,
`map_lat` varchar(100) DEFAULT NULL,
`map_long` varchar(100) DEFAULT NULL,
`show_map` varchar(3) DEFAULT 'no',
`total_view` bigint(20) NOT NULL DEFAULT '0',
`feature_listing` varchar(10) NOT NULL DEFAULT 'no',
`new_homes_id` int(11) NOT NULL,
`publish_price` int(1) NOT NULL DEFAULT '0',
`usd` decimal(20,2) NOT NULL,
`tag_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18524 ;
Have you added indices on your tables? You would need three indices on the following columns:
article_photo.a_id for grouping and joining
article_photo.p_id for sorting
article.a_id for joining (although this is hopefully already the PK of your table)
The result of joins is not guaranteed to be sorted in any order, so you probably want to move your ORDER BY clause from the subquery to the outer query:
SELECT * from `article`
LEFT JOIN (
SELECT * from `article_photo`
GROUP BY `a_id`) as images
ON article.a_id = images.a_id
ORDER BY images.p_id DESC
Also, you have no guarantee on which article_photo you will get, since select data without an aggregate function (and only MySQL will allow you to do that).
Now that the question contains the real tables and all information essential to answering, here's my take – first, here's your query:
SELECT `sp_property`.`id` as propertyid, `sp_property`.`property_name`, `sp_property`.`property_price`, `sp_property`.`adv_type`, `sp_property`.`usd`, `images`.`filepath_name`
FROM (`sp_property`)
LEFT JOIN (select id, Max(property_id) as pid,filepath_name
from sp_property_images
group by property_id) `images`
ON `images`.`pid` = `sp_property`.`id`
WHERE `sp_property`.`published` = 'yes'
GROUP BY `propertyid`
ORDER BY `sp_property`.`feature_listing` desc, `submit_date` desc
LIMIT 1,20
Let's see. you are joining sp_property_images.property_id with sp_property.id. These columns have different types (int vs. varchar) and I suppose this results in a severe performance penalty (since the values have to be converted to the same type).
Then, you are filtering by sp_property.published, so I suggest adding an index on this column as well. Also, examine if you really need to have this column as varchar. A bool/bit flag probably suffices as well (if it doesn't, an enum might be a better choice still).
Ordering benefits from an index too. Add an index spanning both columns sp_property.feature_listing and sp_property.submit_date.
If all of the above still doesn't help, you might have to remove the sub-select. It might prevent the mysql engine from recognizing (and using!) the index you have defined on the sp_property_images.property_id column.
This simple query will give you what you asked for, all articles with their photos
SELECT ar.a_id, ar.a_title, ap.p_id, ap.photo_name
FROM article ar
JOIN article_photo ap on ar.a_id = ap.a_id
No reason for left join and grouping there or you wanna get sum on photos by article?

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