যেখানে ক্লজ [বন্ধ] এর বিকল্প


16

SELECTব্যবহার না করে কোনও কলামে নির্দিষ্ট ডেটা সহ কেবল সারি করার কোনও উপায় আছে?WHERE ?

যেমন আমার যদি এটি ছিল:

SELECT * FROM Users
WHERE town = 'Townsville'

এর মধ্যে WHEREধারাটি কার্যকর করার একটি উপায় আছেSELECTবিবৃতিতে কি?

কিছুটা এইরকম

SELECT *, town('Townsville') FROM Users

এটি একটি উদ্ভট প্রশ্ন তবে এটি আমার মিত্ররা আমাকে জিজ্ঞাসা করেছিল


4
তারা কেন এটি জিজ্ঞাসা করছে তাদের জিজ্ঞাসা করুন। প্রসঙ্গটি গুরুত্বপূর্ণ।
অ্যারন বারট্রান্ড

@ অ্যারোনবার্ট্র্যান্ড, মিকেল এরিকসন - মূলত এটি এসকিউএল সম্পর্কে কর্মক্ষেত্রে একটি সামান্য প্রশ্নপত্র রয়েছে, আমি একটি প্রশ্ন নিয়ে এসেছি যেখানে "টাউনসভিল থেকে আসা ব্যবহারকারীদের সারণি থেকে সমস্ত ব্যবহারকারী নির্বাচন করুন, যেখানে কোনও ধারা ব্যবহার না করেই" এবং, আমি জানতাম না যে সম্ভব ছিল! আমি কি এই ভুল পথে এগিয়ে যাচ্ছি ..?
জোশ স্টিভেনসন

এছাড়াও কেবল উল্লেখ করে যে এই প্রশ্নপত্রটি কোনওভাবেই আমার সংস্থার সাথে আমার নিয়োগের স্থিতির সাথে যুক্ত নয়! এটি কেবল খানিকটা মজাদার
জোশ স্টিভেনসন

উত্তর:


17

নিশ্চিত নয় যে এটি যে ধরণের পাগল জিনিস আপনি খুঁজছিলেন তা যদি হয় ....

দাবি অস্বীকার : আপনি কেন এটি ব্যবহার করতে চান তা সম্পর্কে আমার কোনও ধারণা নেই।

SELECT * 
FROM Users AS u
INNER JOIN (SELECT 'Townsville' town) towns 
  ON towns.town = u.Town;

17

উপাত্ত

DECLARE @Example AS table
(
    UserName varchar(30) NULL,
    Town varchar(30) NULL
);

INSERT @Example
    (UserName, Town)
VALUES
    ('Aaron', 'Not Townsville'),
    ('Bob', 'Not Townsville'),
    ('Charles', 'Townsville'),
    ('Charles', 'Townsville'),
    ('Charles', 'Townsville'),
    ('Charles', 'Townsville'),
    ('Dan', 'Townsville'),
    ('Eric', 'Not Townsville');

বিকল্প সমাধান

SELECT E.UserName, E.Town
FROM @Example AS E
GROUP BY E.Town, E.UserName
HAVING E.Town = 'Townsville'

-- OR

SELECT E.UserName, 'Townsville' AS Town
FROM @Example AS E
GROUP BY E.UserName
HAVING 1 = MAX(CASE WHEN E.Town = 'Townsville' THEN 1 ELSE 0 END);

-- OR

SELECT E.UserName, E.Town
FROM @Example AS E
INTERSECT
SELECT E.UserName, 'Townsville' AS Town
FROM @Example AS E

সদৃশ পুনরুদ্ধার করা

-- :)
SELECT E.UserName, E.Town
FROM @Example AS E
CROSS APPLY (VALUES(NEWID())) AS CA (n)
GROUP BY E.Town, E.UserName, CA.n
HAVING E.Town = 'Townsville'

-- Simulating INTERSECT ALL
SELECT
    R.UserName,
    R.Town
FROM 
(
    SELECT 
        E.UserName, 
        E.Town, 
        rn =
            ROW_NUMBER() OVER (
                PARTITION BY E.UserName, E.Town 
                ORDER BY E.UserName, E.Town)
    FROM @Example AS E
    INTERSECT
    SELECT 
        E.UserName, 
        'Townsville', 
        rn = 
        ROW_NUMBER() OVER (
            PARTITION BY E.UserName 
            ORDER BY E.UserName)
    FROM @Example AS E
) AS R;

আউটপুট:

╔══════════╦════════════╗
 UserName     Town    
╠══════════╬════════════╣
 Charles   Townsville 
 Dan       Townsville 
╚══════════╩════════════╝

চূড়ান্ত উদাহরণের জন্য:

╔══════════╦════════════╗
 UserName     Town    
╠══════════╬════════════╣
 Charles   Townsville 
 Charles   Townsville 
 Charles   Townsville 
 Charles   Townsville 
 Dan       Townsville 
╚══════════╩════════════╝

এটি এখানে চেষ্টা করুন: Stack Exchange Data Explorer


খুব সুন্দর! আমি অনুমান করছি যে আমি এমন একটি দৃশ্যে এটি ব্যবহার করতে সক্ষম হব না যেখানে আমার কাছে কেবল 'ব্যবহারকারীর নাম' এর মতো অনন্য ডেটাযুক্ত কলাম নেই? উদাহরণস্বরূপ যদি আমার কেবল নাম, নাম, শহর থাকে।
জোশ স্টিভেনসন

3
@ জোস্টস্টেভেনসন সঠিক, যদিও আমি নকলকে চূড়ান্ত উদাহরণ হিসাবে সংরক্ষণ করার জন্য একটি উপযুক্ত পাগল পথ যুক্ত করেছি এবং তারপরে একটি বোধগম্য।
পল হোয়াইট পুনর্নির্মাণ মনিকা

1
জন্য GROUP BYসমাধান, আপনার কাছে পি কে দলের তালিকা যোগ করতে পারেনি (নিশ্চিত 100% হতে যে প্রশ্নের কোথায় যেমন সারি একই সংখ্যক আসতে)। অবশ্যই ধরে নেওয়া হচ্ছে যে সেখানে একটি পিকে আছে;)
ypercubeᵀᴹ


14

"কেবল মজাদার জন্য" আপনি একটি ব্যবহার করতে পারেন order by সঙ্গেtop(1) with ties

select top(1) with ties *
from dbo.Users
order by case when town = 'Townsville' then 1 else 2 end;

Townsvilleকেস ফিরে আসার পরে এটি প্রথম সহ সমস্ত সারি অর্ডার করবে1 যদি town = 'Townsville'। অন্যান্য সমস্ত সারিতে একটি থাকবে2 কেস দ্বারা ফিরে আসবে।

দ্য with tiesদফা ক্যোয়ারী সব সারি সারি ফিরে গত স্থানের জন্য একটি "টাই" যে আসতে করে তোলে। top(1)সাথে সংমিশ্রণে ব্যবহার করাwith ties ব্যবহার করা হলে ক্লজ দ্বারা ক্রমে প্রকাশিত প্রথম সারির সমান মানযুক্ত সমস্ত সারি ফিরে আসবে।

দ্রষ্টব্য, মার্টিন স্মিথ একটি মন্তব্যে যেমন উল্লেখ করেছেন, এটি ফিরে আসবে সমস্ত সারি দেবে আপনি যদি টেবিলটিতে অস্তিত্বহীন একটি শহর চান তবে ।

আপনি যদি ডাটাবেসের এক্সএমএল বিষয়গুলি ভয় না পান তবে আপনি নোড () ফাংশনে একটি প্রিকিকেট ব্যবহার করতে পারেন।

পল হোয়াইটের কাছ থেকে সেটআপ ধার করা।

select T.X.value('(UserName/text())[1]', 'varchar(30)') as UserName,
       T.X.value('(Town/text())[1]', 'varchar(30)') as Town
from (
     select *
     from @Example
     for xml path('row'), type 
     ) as C(X)
  cross apply C.X.nodes('/row[Town = "Townsville"]') as T(X);

বিদ্যমান নগরগুলির সন্ধান করার সময় topএবং এর সাথে অন্য একটি সংস্করণ order byআসলে কাজ করে।

select top(
          select sum(case when town = 'Townsville' then 1 end)
          from @Example
          ) *
from @Example
order by case when town = 'Townsville' then 1 else 2 end

7

আপনার এখানে দুটি আলাদা জিনিস রয়েছে।

SELECT * FROM Users
WHERE town = 'Townsville'

আপনি যেখানে টাউন = তে ফিরে পাবেন এমন সারিগুলির সংখ্যা সীমাবদ্ধ করবেTownsville

SELECT *, town('Townsville') FROM Users

আক্ষরিক Townsvilleবলা একটি ফাংশন পাস করতে যাচ্ছেtown । এটি ক্যোয়ারী দ্বারা ফিরে আসা সারিগুলিকে সীমাবদ্ধ করবে না এবং প্রকৃতপক্ষে যদি ফাংশনটি একটি মান ব্যতীত অন্য কিছু দেয় তবে আপনি ত্রুটি পাবেন।

সন্ধানের সংখ্যাটি সীমাবদ্ধ করার অন্যান্য উপায় রয়েছে যেগুলি আপনি কোয়েরি থেকে ফিরে পেয়েছেন। উদাহরণস্বরূপ HAVING ধারাটি। তবে এর অন্যান্য বেশ কয়েকটি প্রয়োজনীয়তাও রয়েছে।

SELECT town FROM Users
GROUP BY town
HAVING town = 'Townsville'

বা একটি অভ্যন্তরীণ যোগদান যদিও আপনার কাছে দ্বিতীয় সারণী না থাকলে এটি কিছুটা অদ্ভুত।

SELECT * FROM Users
INNER JOIN (SELECT 1 col1) UselessTable
    ON Users.town = 'Townsville'

5

সাধারণ টেবিল এক্সপ্রেশন (সিটিই) ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হল।

with Town as 
(
    select 'Townsville' as Town
)
select *
  from Users u
  join Town  t on u.Town = t.Town

5

ভাল আপনি এই করতে পারে:

    SELECT A.* 
    FROM Users A
         INNER JOIN Users B ON A.Id = B.Id AND B.town = 'Townsville'

কঠোরভাবে বলতে গেলে আপনি WHERE ধারাটি ব্যবহার করছেন না


5

এটি করার জন্য এখানে একটি বোকামি পুরোপুরি যৌক্তিক উপায় যা আমি এখনও দেখতে পাচ্ছি না ....

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;  -- Our important work should be all the database cares about
GO
BEGIN TRANSACTION

DECLARE @MyTableVar table(<all columns in order from the user table>, oldtown VARCHAR(50));

UPDATE users
SET town = N'Townsville'
OUTPUT 
     inserted.*  -- We don't want to have to type out the columns because that would be too much work
    deleted.town
INTO @MyTableVar;

--Display the result set of the table variable to prevent undesirables from sullying our output by inserting incorrect data even though we should have exclusive access.
SELECT * -- Select everything we want except for the 'oldtown' column because that data was probably wrong anyway
FROM @MyTableVar;

UPDATE u -- We don't want to be bad stewards of our data
SET
    town = oldtown
FROM users u
    INNER JOIN @MyTableVar mtv ON mtv.town = u.town, <Match up all the columns to REALLY ensure we are matching the proper row>

COMMIT TRANSACTION -- Make sure we save our work

কেন এটি প্রথম জিনিস বলে প্রস্তাব করা হয়নি তা আমি ভাবতে পারি না। :)


-2
SELECT *, 
    case when town='Townsville' then 'Townsville' 
         else null 
    end as Town
FROM Users

টাউনসভিলের পাশের সমস্ত শহরগুলি শূন্য হবে। সমস্যা সমাধান.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.