How to fetch non-translated data in this given scenario - sql

Suppose in my application, I am inserting a few data(here questions) in a specific table in SQL SERVER.
-------------------------------------------
TBL_QUESTIONS
-------------------------------------------
question_id|subj_code_id|question_text
-----------|------------|------------------
1 | 1 | A basic question
-----------|------------|------------------
2 | 1 | Another Question...
-----------|------------|-------------------
3 | 1 | Again a question
Now anything that I entered in this table has a culture of en-US.
Currently, I have the following cultures.
-------------------------------
TBL_LANG_CULTURE
-------------------------------
lang_id|lang_name|culture_name
-------|---------|-------------
1 | English | en-US
2 | Hindi | hi-IN
3 | French | fr-FR
Now there is another table which is storing translated part of those questions...
----------------------------------------
TBL_TRANSLATED_QUESTINS
---------------------------------------
question_id| lang_culture|question_text
-----------|-------------|---------------
1 | hi-In | एक बुनियादी सवाल
-----------|-------------|----------------
2 | hi-In | एक और सवाल
-----------|-------------|----------------
2 | fr-FR | Une autre question
Now, If I want to display how many questions are there which is not translated yet in French. Then the output should look like this,
question_id| English_TEXT | TRANSLATED_TEXT
-----------|-------------------|-----------------
1 | A basic question |
-----------|-------------------|-----------------
3 | Again a question |
And now, If I want to display how many questions are there which is not translated yet in Hindi. Then the output should look like this,
question_id| English_TEXT | TRANSLATED_TEXT
-----------|-------------------|-----------------
3 | Again a question |

Try this-
SELECT *
FROM TBL_QUESTIONS A
LEFT JOIN TBL_TRANSLATED_QUESTINS B
ON A.question_id = B.question_id
AND lang_culture = 'fr-FR' -- To check French
WHERE B.question_id IS NULL

This result can be achieved by using join and then filter. Something like below might help you -
SELECT TQ.question_id, TQ.question_text, TTQ.question_text
FROM TBL_QUESTIONS TQ
LEFT JOIN (SELECT question_id, lang_culture, question_text
FROM TBL_TRANSLATED_QUESTINS TT2
WHERE TTQ.question_id IN (SELECT DISTINCT question_id
FROM TBL_LANG_CULTURE TLC
INNER JOIN TBL_TRANSLATED_QUESTINS TTQ ON TLC.culture_name = TTQ.lang_culture
WHERE lang_name = 'French')) ON TQ.question_id = TTQ.question_id
WHERE TQ.question_id IS NULL
I have not tried it yet, but this should work for you.

Related

Need advice about JOIN by LIKE operator

I have two data tables, one contain the customer data such as customer ID and used bonus codes. The second table is for internal notes, every note that i write about the customer is there, for example: gave to customer 12 bonus code GFT100.
know i need join this two table based on the bonus code, i want for every bonus code the player used to find the relevant note in the notes table.
Table 1: Used bonus codes
CustomerID | Coupon_Code | DateOfUsege
--------------------------------------
12 | AAA25 | 2016-09-10
-------------------------------------
12 | BBB13 | 2016-09-10
--------------------------------------
17 | CCC14 | 2016-09-10
Table2:Customer Notes
CustomerID| Date | Text
---------------------------------------------
12 |2016-09-07| Gave bonus AAA25
----------------------------------------------
12 |2016-09-07| Very good customer
----------------------------------------------
17 |2016-09-06| Gave bonus code CCC14
Desired output: for each used code in table 1 add only the relevant note from table 2
CustomerID | Coupon_Code | DateOfUsege | Text |
----------------------------------------------------------------
12 | AAA25 | 2016-09-10 | Gave bonus AAA25 |
----------------------------------------------------------------
17 | CCC14 | 2016-09-10 | Gave bonus code CCC14 |
-----------------------------------------------------------------
How can i do that?
I'd advise adding a nullable coupon_code column to your notes table (assuming a note may only pertain to zero or one coupon code) and recording the optional code with each note when applicable. Searching for the code in the free text values could return false positives
... but, this join should get you started
SELECT a.CustomerID, a.Coupon_Code, a.DateOfUsege, b.Text
FROM `used_bonus_codes` a
INNER JOIN `customer_notes` b
ON a.CustomerID = b.CustomerID
AND b.Text LIKE CONCAT('%', a.Coupon_Code, '%')

SQL Server : query with subquery involving select from previous selection

I'm trying to create a query in SQL Server to determine how many times a person's name shows up in a list, but also that list will be unknown, so I would have to get the actual name from the previous select index... It's hard to explain so I'll show the query first and hopefully someone can help.
SELECT
SpeakerName, Spoken,
(SELECT COUNT(SpeakerName)
FROM tbl_SpeakerCard_Log
WHERE SpeakerName = 'SpeakerName[i]' AND SpeakDate = '3-9-16') as TimesSpoken
FROM
tbl_SpeakerCard_Log
WHERE
AID = ####
ORDER BY
GeneralComment ASC
So basically, in SpeakerName[i], I'd like to somehow get the SpeakerName from the outer Select. The output should come out something like this
+-------------+--------+-------------+
| SpeakerName | Spoken | TimesSpoken |
+-------------+--------+-------------+
| Holly | 0 | 4 |
| Robert | 1 | 5 |
| Mike | 1 | 2 |
+-------------+--------+-------------+
Try this:
select x.SpeakerName, x.Spoken, COUNT(*) as TimesSpoken
from tbl_SpeakerCard_Log x
WHERE AID = ####
and x.SpeakDate = '3-9-16'
group by x.SpeakerName, x.Spoken
Don't have SSMS installed on this computer so can't test it.

Access SQL Max-Function

I have a question concerning MS Access queries involving these tables:
tblMIDProcessMain ={ Process_ID,Process_Title,...}
tblMIDProcessVersion = { ProcessVersion_ID, ProcessVersion_FK_Process, ProcessVersion_VersionNo, ProcessVersion_FK_Status, ...}
tblMIDProcessVersionStatus = { ProcessVersionStatus_ID,ProcessVersionStatus_Value }
The tables store different versions of a process description. The "ProcessVersion_VersionNo" field contains an integer providing the version number. Now I would like to get for each process the highest version number thus the current version. If I do the following it kind of works:
SELECT tblMIDProcessMain.Process_Titel
, Max(tblMIDProcessVersion.ProcessVersion_VersionNo) AS CurrentVersion
FROM tblMIDProcessMain
INNER JOIN tblMIDProcessVersion
ON tblMIDProcessMain.Process_ID = tblMIDProcessVersion.ProcessVersion_FK_Process
GROUP BY tblMIDProcessMain.Process_Titel;
The query returns a recordset with each existing process_title and the respective max number of the version field. But as soon as I add other fields like "ProcessVersion_FK_Status" in the Select statement the query stops working.
Any help would be appreciated. Thanks in advance.
Jon
Edit:
To clarify things a little I added a simplified example
Parent-Table:
Process_ID | Process_Title
----------------------------------
1 | "MyProcess"
2 | "YourProcess"
Child-Table:
Version_ID | Version_FK_ProcessID | Version_No | Version_Status
---------------------------------------------------------------------------
1 | 1 | 1 | "New"
2 | 2 | 1 | "Discarded"
3 | 2 | 2 | "Reviewed"
4 | 2 | 3 | "Released"
Intended Result:
Title | Max_Version_No | Status
--------------------------------------------------------
MyProcess | 1 | "New"
YourProcess | 3 | "Released"
Given the example tables you updated your post with, this should work:
select process_title as Title
, max_version.max_version_no
, c.version_status as status
from (parenttable p
inner join (select max(version_id) as max_version_no, version_fk_process_id from childtable group by version_fk_process_id) max_version
on p.process_id = max_version.version_fk_process_id)
inner join childtable c
on max_version.max_version_no = c.version_id and max_version.version_fk_process_id = c.version_fk_process_id
I assume you are adding the new field to the 'Group By" clause? If not, then you either must include in the 'Group By', or you must use one of the operators like "Max" or "First" etc.

How do I do a WHERE NOT IN for Hierarchical data?

I have a table that is a list of paths between points. I want to create a query to return a list with pointID and range(number of point) from a given point. But have spent a day trying to figure this out and haven't go any where, does any one know how this should be done? ( I am writing this for MS-SQL 2005)
example
-- fromPointID | toPointID |
---------------|-----------|
-- 1 | 2 |
-- 2 | 1 |
-- 1 | 3 |
-- 3 | 1 |
-- 2 | 3 |
-- 3 | 2 |
-- 4 | 2 |
-- 2 | 4 |
with PointRanges ([fromPointID], [toPointID], [Range])
AS
(
-- anchor member
SELECT [fromPointID],
[toPointID],
0 AS [Range]
FROM dbo.[Paths]
WHERE [toPointID] = 1
UNION ALL
-- recursive members
SELECT P.[fromPointID],
P.[toPointID],
[Range] + 1 AS [Range]
FROM dbo.[Paths] AS P
INNER JOIN PointRanges AS PR ON PR.[toPointID] = P.[fromPointID]
WHERE [Range] < 5 -- This part is just added to limit the size of the table being returned
--WHERE P.[fromPointID] NOT IN (SELECT [toPointID] FROM PointRanges)
--Cant do the where statment I want to because it wont allow recurssion in the sub query
)
SELECT * FROM PointRanges
--Want this returned
-- PointID | Range |
-----------|-------|
-- 1 | 0 |
-- 2 | 1 |
-- 3 | 1 |
-- 4 | 2 |
Markus Jarderot's link gives a good answer for this. I end tried using his answer and also tried rewriting my problem in C# and linq but it ended up being more of a mathematical problem than a coding problem because I had a table with several thousands of point that interlinked. This is still something I am interested in and trying to get a better understanding of by reading books on mathematics and graph theory but if anyone else runs into this problem I think Markus Jarderot's link is the best answer you will find.

Complex join with coalesce

I have a table that I am stuffing demographic info into and then using dynamic sql to build a table from that. The demographic info comes from surveys and some of the surveys have checkboxes. With checkboxes people can select multiple values.
So I need to enter all the choices as a comma seperated list.
CREATE TABLE Demographics
(
QID NVARCHAR(15)
,userid NVARCHAR(50)
,question NVARCHAR(800)
,choice NVARCHAR(1000)
)
...
...
--Demographics(QID,userid,question,choice)
--'Insert checkbox (type 5)
INSERT INTO Demographics
SELECT CAST(q.QID AS NVARCHAR(15))
,ri.userid
,q.QuestionText
,ac.Choice
FROM ResponseInfo ri --response details
JOIN Responses r ON ri.ResponseID = r.ResponseID --actual response
JOIN Questions q ON r.QID = q.QID --question info
JOIN AnswerChoices ac ON r.QID = ac.QID --answer choice text
WHERE (q.QuestionTypeID = 5 AND q.QID = ac.QID
AND r.IsOther = 0
AND q.QID = 16
)
AND ri.userid IN (SELECT userid FROM #Users) AND r.Response = ac.Sequence
ORDER BY ri.userid
...
dynamic sql stuff
...
EXEC sp_exesql #sql
My results look like this:
users | question_15 | choice_15 | question_16 | choice_16 |
bill | age? | 37 | favorite color? | red |
bill | age? | 37 | favorite color? | green |
But it needs to be:
users | question_15 | choice_15 | question_16 | choice_16 |
bill | age? | 37 | favorite color? | red,green |
I tried doing
,COALESCE(ac.Choice + ',','') + ac.Choice
It gave me
bill | age? | 37 | favorite color? | red,red |
Can anyone help me sort this out?
It looks like you are using SQL Server. If you're using a recentish version of SQL Server (e.g., SQL Server 2005 or later), you'd likely be better off storing your data as XML.
That lets you use XPATH/XQUERY in SQL to manipulate the XML data to get what you want. I think you'll find that easier to do.
http://www.simple-talk.com/sql/learn-sql-server/sql-server-xml-cribsheet/
http://www.simple-talk.com/sql/t-sql-programming/beginning-sql-server-2005-xml-programming/
Found this.
Very helpful. My code could probably use some cleaning up.