How to add an individual feild in the view - mysql

i am trying to make a view in MS SQL having join of two table and an individual field.
i have done the joining part but now i want to add a new field in this view which is not in any of the table which is joined.
so anybody have any idea how i can create this new field in the view.

In case you want a default value for all your rows in the ACTIVE field, try this
CREATE VIEW Slots AS
SELECT Event.EventId,
Event.eventName,
examCenter.centerId,
examCenter.centerName,
slotTime.slotTimeId,
slotTime.FromTime,
slotTime.ToTime,
slotTime.Dated,
examCenter.noOfSeats,
CAST(1 AS bit) AS Active
FROM examCenter
INNER JOIN Event
ON examCenter.eventId = Event.EventId
INNER JOIN slotTime ON Event.EventId = slotTime.eventId
If the value for the ACTIVE field depends on some condition, say
slottime.Dated => getdate()
then, you will need to replace
CAST(1 AS bit) AS Active
in the above code, with
CAST(CASE WHEN slottime.Dated => getdate() THEN 1 ELSE 0 AS bit) AS ACTIVE

You can explicitly name each field if you need, aliasing them with AS as required. For example:
SELECT si.field1 as si_field1,
si.field2 as si_field2,
ind_data.field1 as ind_data_field1
FROM sites_indexed as si
LEFT JOIN individual_data as ind_data
ON si.id = ind_data.site_id
And then you can reference the aliased names in your result set.

Related

Using SELECT clause in ELSE part of SQL query?

I have two tables.
Table number 1 (Lab_test): with integer columns named labtest_id (pk) and project_no. Second table (Project) has two columns, first column named project_id (int) and second column project_name (string). Also I have two parameters which are passed to the query.
I have to make a query which will extract labtest_id and proj_num. proj_num have to be obtained in following way: if Lab_test.project_no is not null, take this value, else go to referencing table Project and take project_name.
I tried with bunch of combinations using SQL CASE IF-THEN-ELSE statements, but no luck:
SELECT lab.labtest_id, proj_num,
FROM Lab_test lab
(CASE
WHEN lab.project_no IS NOT NULL THEN lab.project_no
ELSE (SELECT proj.project_name
FROM Project proj
WHERE proj.project_id = lab.project_no)
) AS proj_num
WHERE lab.status = 'DONE' AND lab.user_id = 436
You can use left join and coalesce() to replace the case when expression that you've used to check null
SELECT lab.labtest_id, coalesce(lab.project_no,proj.project_name) as proj_num
FROM Lab_test lab
left join Project proj on proj.p,roject_id = lab.project_no
where lab.status = 'DONE' AND lab.user_id = 436
if Lab_test.project_no is not null, take this value, else go to referencing table Project and take project_name.
I don't believe you. I think you have the logic backwards -- use the referenced table if it is available. Otherwise use the number.
That would suggest:
SELECT l.labtest_id, COALESCE(p.project_name, l.project_no) as proj_num
FROM Lab_test l LEFT JOIN
Project p
ON p.p,roject_id = l.project_no
WHERE l.status = 'DONE' AND l.user_id = 436;
If the project_no is a number, then you might have a type conversion problem. If that is an issue:
SELECT l.labtest_id,
COALESCE(p.project_name, CAST(l.project_no as CHAR)) as proj_num
FROM Lab_test l LEFT JOIN
Project p
ON p.p,roject_id = l.project_no
WHERE l.status = 'DONE' AND l.user_id = 436;

Use ValueA when JOIN returns a row, otherwise ValueB (like a default)

I have four tables for a form-builder in my databse.
fields (fieldID(PK), typeID, fieldName, ...) - This table is a row by row list of all fields to be in the form
fields_types (typeID(PK), htmlType, ...) - This is a table that links fields to html types (and other settings)
fields_meta (FieldMetaID(PK), FieldID, mName, mValue) - Additional settings for fields, but more specific. A textarea field might have a height attribute, but almost no other field would use that.
fields_tyeps_meta (TypeMetaID(PK), typeID, tmName, tmValue) - Defines what extraneous settings a field can have, and also supplies default values if it's not explicitly set)
So my Query currently looks something like this
SELECT *
FROM Fields F
JOIN Field_Types FT
on FT.FieldID = F.FieldID
LEFT
JOIN Field_Meta FM
on FM.FieldID = F.FieldID
I was wondering if there's a way to join Fields_Types_Meta so that when the row's JOIN to Fields_Meta doesn't return a row (no mValue), it returns tmValue
I realize I can use something like (CASE WHEN mValue = "" THEN tmValue ELSE mValue END) AS UseValue, but I might have fields where I want to allow the value to be set to empty.
Edit: I could probably do something with a subquery and COUNT, using a CASE decision based on that. It might not be the healthiest performance-wise, but this query runs and caches itself til server restart, or until it's told to run again (updates to form design)
It looks like you just want ¢oalesce():
coalesce(FM.mValue, FT.tmValue) as UseValue
When FM.mValue is null, coalesce() returns FT.tmValue instead.
If you have null values in FM that you want to preserve in the result set, then use a case expression instead:
case when FM.FieldID IS NULL THEN FT.tmValue ELSE FM.mValue END as UseValue
This phrases as: when the left join did find a match in FM, use mValue from that row (even if it is null), else use FT.tmValue.

SQL Joining Diffrent Size Tables Together With Null Value Replacement

I am working on a query for a datatable and I can't seem to get it to display how I want, I don't know if this is even possible in SQL What I am looking to do is get a query to respond with ideally an extra column of Boolean type.
Currently I can run two queries and they both work perfectly but I can't work out how to join them together bellow is the code from my first query what this does is return beers a user has tried this works fine and as expected and returns as expected.
SELECT *
FROM keg.beer
JOIN keg.userbeer
ON beer.id = userbeer.beer_id
WHERE userbeer.username_id = 1;
The second query is even simpler and is just a select getting the list of beers.
SELECT * FROM keg.beer
What I want to do is run a query and have it return a list of beers with a Boolean value if the user has tried it or not.
You're not going to run into too many scenarios for "Desired Results" that can't be produced with plain 'ol SQL. In this case you'll use a CASE statement to determine if the person has tried a beer. You'll also want a LEFT OUTER JOIN so you don't drop records coming from your beer table when your filtered userid doesn't have a userbeer record for that beer:
SELECT
beer.name,
beer.id,
beer.country,
CASE WHEN userbeer.username_id IS NULL THEN 0 ELSE 1 END AS user_tried_beer_boolean
FROM keg.beer
LEFT OUTER JOIN keg.userbeer
ON beer.id = userbeer.beer_id
AND userbeer.username_id = 1;
As #SeanLange mentioned in the comments here, the restriction of the WHERE statement for the userid would cause records to be dropped that you want in your result set, so we move the restriction of username_id = 1 to the ON portion of the LEFT OUTER JOIN so that the userbeer table results are restricted to just that user before it's joined to the beer table.
Now I need a drink.
SELECT b.id,
b.name,
CASE WHEN u.username_id IS NOT NULL THEN TRUE ELSE FALSE END AS userdrankbeer
FROM keg.beer b
LEFT JOIN ( SELECT * FROM keg.userbeer WHERE username_id = 1 ) u
ON beer.id = userbeer.beer_id
;

MySQL SubQuery Conditional

I am trying to build a rather complex view in MySQL and want to do a conditional, but it sems always to fail.
My view (simplified) is
Select entry AS Entry, ,(select count(`poitems`.`entry`) AS `count(poitems.entry)` from `poitems` where (`poitems`.`PurchaseOrder` = `purchaseorder`.`entry`)) AS `TotalEntries`, from purchase orders
this is OK but what I am trying to do is add something like
if ((select count(`poitems`.`entry`) = 0),'query.png',NULL) AS Queryflag
or just test the value of TotalEntries.
Help appreciated! Thanks!
I'm not 100% sure on the names of the columns in purchaseorder or poitems tables but the following should get you headed in the right direction:
select t.Entry,
case when t.TotalEntries > 0 then 'query.png' else null end as Queryflag
from
(
select po.entry as Entry,
count(*) as TotalEntries
from purchaseorder po
left outer join poitems poi on poi.purchaseorder = po.entry
group by po.entry
) t;

LEFT JOIN query returns multiple results

I have the query below which looks at a table of data in which each line has an ID, date/time and key action (as well as other data). This table cannot be changed and is out of my control.
The query finds an occurrence of the Create action (which is always the first) pulls the ID and Date/Time for Creation and then pulls the Date/Time of the other key actions (Add Info, Book Appt, Accept) in one row of data:
SELECT _create.ID AS ID,
_create.`datetime` AS Create,
_inform.`datetime` AS Add_Info,
_bookap.`datetime` AS Book_Appt,
_accept.`datetime` AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
So I get something like:
ID - Create Date - Inform Date - Bookap Date - Accept Date
1234 01/02/2013 02/02/2013 09/02/2013 10/02/2013
This works well.
However if the query finds 2 events of the same type ie 'Book Appt' for the same ID, which can happen sometimes, it pulls two lines of data for that ID. So I get:
ID - Create Date - Inform Date - Bookap Date - Accept Date
1234 01/02/2013 02/02/2013 09/02/2013 10/02/2013
1234 01/02/2013 02/02/2013 15/02/2013 10/02/2013
I need it to ignore the second occurence and only return one line per ID. Or, even better return a line showing Bookap Date1 and Bookap Date2.
Any ideas?
Use GROUP BY to group the records into one row, and min() to select the earliest event date.
SELECT _create.ID AS ID,
min(_create.`datetime`) AS Create,
min(_inform.`datetime`) AS Add_Info,
min(_bookap.`datetime`) AS Book_Appt,
min(_accept.`datetime`) AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
GROUP BY _create.ID;
A quick and dirty way to show all event dates but still return one row is to use the group_concat() function instead of min() in the query above. This would put multiple datetimes into single columns which your app layer would then need to parse.
Sure, use GROUP BY _create.ID after your WHERE clause.
If you want to return multiple Book_Appt values in a single row, you can use GROUP_CONCAT like this:
SELECT _create.ID AS ID,
_create.`datetime` AS Create,
_inform.`datetime` AS Add_Info,
GROUP_CONCAT(_bookap.`datetime`) AS Book_Appt,
_accept.`datetime` AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
GROUP BY `ID`
This would return a comma-seperated list of datetime values in your case.
So your output might look like
ID - Create Date - Inform Date - Bookap Date - Accept Date
1234 01/02/2013 02/02/2013 09/02/2013,15/02/2013 10/02/2013
For your first question (to return only one row) I would use an ORDER BY clause to sort your result set, followed by a LIMIT 1 expression to only return one row.