Select statement involving SET data type - mysql

How to use the SET datatype in MySQL? I have a table Train in which there are fields
trainno int
Weekdays set data type
Stops set data type
train name
How to write a select query where I can compare the Stops set with a particular value like 'Mumbai'?

Create a table like:
CREATE TABLE cl_db.Train
(
trainno INT PRIMARY KEY AUTO_INCREMENT,
Stops set('aaa','bbb','ccc') NOT NULL
)
and you can query it like
select * from cl_db.Train where Stops like 'bbb'
or like
select * from cl_db.Train where FIND_IN_SET('bbb',Stops)>0;

Related

Get full value from column char(1)

I have the following table for storing information about student attendance:
attendance
( id INT(11)
, type CHAR(1)
, for_date DATETIME
);
When inserting a new record, Present, 2017-11-26, MySQL stores P in type column.
So I'm trying to get full value Present in dashboard page with SELECT query but fails.
Is it possible to get full value without change datetype of column?
Here's what I did:
SELECT `id`, CONVERT(`type`, CHAR(10)) AS type, `for_date` FROM `attendance`;
You should store the full text eg:
attendance
( id INT(11)
, type CHAR(16)
, for_date DATETIME
);
so you obtain all text using select ...
otherwise you should decode the returning values eg. using case when
SELECT `id`, case when type = 'P' then 'Present' end as my_type, `for_date`
FROM `attendance`;

Does my Full-Text Index already contain a particular value?

I've got a SQL 2008 R2 table defined like this:
CREATE TABLE [dbo].[Search_Name](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](300) NULL),
CONSTRAINT [PK_Search_Name] PRIMARY KEY CLUSTERED ([Id] ASC))
Performance querying the Name field using CONTAINS and FREETEXT works well.
However, I'm trying to keep the values of my Name column unique. Searching for an existing entry in the Name column is unbelievably slow for a large number of names (usually batches of 1,000), even with an index on the Name field. Query plans indicate I'm using the index as expected.
To search for an existing value, my query looks like this:
SELECT TOP 1 Id, Name from Search_Name where Name = 'My Name Value'
I've tried duplicating the Name column to another column and searching on the new column, but the net effect was the same.
At this point, I'm thinking I must be mis-using this feature.
Should I just stop trying to prevent duplication? I'm using a linking table to join these search name values to the underlying data. It seems somehow 'dirty' to just store a whole bunch of duplicate values...
...or is there faster way to take a list of 1,000 names and see which ones are already stored in the database?
The first change to make is to get the entire list to SQL Server at one time. Regardless of how you add the names to the existing table, doing it as a set operation will make a big difference in performance.
Passing the List as a table-valued parameter (TVP) is a clean way to handle it. Have a look here for an example. You can still use an OUTPUT clause to track which rows did or didn't make the cut, for example:
-- Some sample existing names.
declare #Search_Name as Table ( Id Int Identity, Name VarChar(32) );
insert into #Search_Name ( Name ) values ( 'Bob' ), ( 'Carol' ), ( 'Ted' ), ( 'Alice' );
select * from #Search_Name;
-- Some (prospective) new names.
declare #New_Names as Table ( Name VarChar(32) );
insert into #New_Names ( Name ) values ( 'Ralph' ), ( 'Alice' ), ( 'Ed' ), ( 'Trixie' );
select * from #New_Names;
-- Add the unique new names.
declare #Inserted as Table ( Id Int, Name VarChar(32) );
insert into #Search_Name
output inserted.Id, inserted.Name into #Inserted
select New.Name
from #New_Names as New left outer join
#Search_Name as Old on Old.Name = New.Name
where Old.Id is NULL;
-- Results.
select * from #Search_Name;
-- The names that were added and their id's.
select * from #Inserted;
-- The names that were not added.
select New.Name
from #New_Names as New left outer join
#Inserted as I on I.Name = New.Name
where I.Id is NULL;
Alternatively, you could use a MERGE statement and OUTPUT the names that were added, those that weren't, or both.

How to select some default value if there is no such column in a table?

For example, I have a table that doesn't have a column "type". But I need to have my sql query having that column. When I run the query I get an error:
SELECT t.foo, t.boo, t.type FROM tabl AS t;
Unknown column 't.type' in 'field list'
I need something like ternary operator. I tried these solutions but they both do not work:
SELECT f.foo, f.boo, IF(f.type IS NULL, 'x', f.type) AS type FROM tabl AS f
SELECT f.foo, f.boo, (CASE WHEN f.type IS NULL THEN "x" ELSE f.type) AS type FROM tabl AS f
Is there a possibility to implement such a query?
Use something like this. Assume you want to join 2 tables rows and one is missing the column:
SELECT t.foo, t.boo, t.type FROM tabl1 as t1
UNION
SELECT t.foo, t.boo, NULL as type FROM tabl2 AS t2;
You can replace NULL with a string "" or whatever you application desires.
Unfortunately, that is not the way columns work. If you need to introspect your table to determine if it have this column, then you might try using data in the information_schema to get at this. Overall sounds like a weird approach to me. Why not just create all the tables with this column?
I think you mean that you have a table with entries ... Some of your entries has got no "type" column filled in. To have default value, you need to change your table. You can change it using either phpmyadmin (set default value) or through SQL code.
This would be something on these lines:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'London'
)
This sets each entry's city to be London by default

Dynamically pick field to select data from

Say I have a table with three columns primaryNum, secondaryNum, chosenNum. primarynum and secondaryNum are both number values but chosenNum's value can either be "primaryNum", "secondaryNum", or "both".
The chosenNum field is a column that gives me the option to search for a number in a particular field.
For example: I might want to try to find all rows with the value 10 in the column that is stored in chosenNum. If the value of chosenNum is "both" then the row would be returned if either column (primaryNum, secondaryNum) had a value of 10.
What might my select statement look like?
It might be a better scenario if I say I would like to do a select statement like:
SELECT * FROM aTable WHERE (SELECT bVal FROM bTable WHERE aVal = #varField ) = 0;
Where #varField is the value of the value in the field with the label stored in chosenNum or either field if chosenNum = "both"
This would result in me getting back rows with id 1,2,3,4,6,7,14,15,16,19,20,21,23,24,27
Table A: Create
CREATE TABLE `test`.`aTable` (
`id` INT NOT NULL AUTO_INCREMENT ,
`primaryNum` INT NULL ,
`secondaryNum` INT NULL ,
`chosenNum` CHAR(12) NULL ,
PRIMARY KEY (`id`) );
Table B: Create
CREATE TABLE `test`.`bTable` (
`aVal` INT NULL ,
`bVal` INT NULL );
Table A: Data
INSERT INTO test.aTable VALUES (1,8,7,'secondaryNum'),(2,2,9,'secondaryNum'),(3,7,9,'both'),(4,5,1,'both'),(5,10,3,'secondaryNum'),(6,10,6,'both'),(7,7,8,'both'),(8,10,2,'primaryNum'),(9,2,1,'secondaryNum'),(10,7,2,'secondaryNum'),(11,2,2,'secondaryNum'),(12,5,1,'secondaryNum'),(13,1,6,'primaryNum'),(14,6,6,'both'),(15,4,9,'both'),(16,9,7,'primaryNum'),(17,8,3,'secondaryNum'),(18,10,7,'primaryNum'),(19,8,5,'secondaryNum'),(20,1,7,'both'),(21,7,9,'both'),(22,8,3,'primaryNum'),(23,6,2,'primaryNum'),(24,5,7,'both'),(25,2,1,'both'),(26,5,2,'secondaryNum'),(27,7,8,'primaryNum');
Table B: Data
INSERT INTO test.bTable VALUES (1,1),(2,1),(3,1),(4,1),(5,0),(6,0),(7,0),(8,1),(9,0),(10,1);
You can do something like this:
select *
from MyTable
where (chosenNum in ('both', 'primaryNum') and primaryNum = 10)
or (chosenNum in ('both', 'secondaryNum') and secondaryNum = 10)

How to specify data type on create table as select in mysql?

When I run attached example, it creates table with column id and data type bigint(295)
I would like to define it as int(11).
In more complex query (I've got ids from group concat) I've got text instead of int.
How to specify data type on create table as select in mysql?
DROP TABLE IF EXISTS some_table;
CREATE TABLE IF NOT EXISTS some_table AS (
SELECT
CONVERT("123,456,789,987,654,321,741,852,963,147,258,369,123,456,789,987,654,321,741,852,963,147,258,369
,2123,456,789,987,654,321,741,852,963,147,258,369,123,456,789,987,654,321,741,852,963,147,258,369
,3123,456,789,987,654,321,741,852,963,147,258,369,123,456,789,987,654,321,741,852,963,147,258,369"
, SIGNED INTEGER) AS id);
I can't find straight way to do it.
Solve it by alter table, worked me, perhaps there is better solution.
DROP TABLE IF EXISTS some_table;
CREATE TABLE IF NOT EXISTS some_table AS (
SELECT
CONVERT("123,456,789,987,654,321,741,852,963,147,258,369,123,456,789,987,654,321,741,852,963,147,258,369
,2123,456,789,987,654,321,741,852,963,147,258,369,123,456,789,987,654,321,741,852,963,147,258,369
,3123,456,789,987,654,321,741,852,963,147,258,369,123,456,789,987,654,321,741,852,963,147,258,369"
, SIGNED INTEGER) AS id);
ALTER TABLE some_table CHANGE id id INT( 11 ) NULL DEFAULT NULL ;