sprawdź ograniczenie tylko jedna z trzech kolumn jest różna od null
<p>mam tabelę (sql server), która zawiera 3 typy wyników: float, nvarchar (30) lub datetime (3 osobne kolumny). chcę się upewnić, że dla dowolnego wiersza tylko jedna kolumna ma wynik, a pozostałe kolumny mają wartość null. jakie jest najprostsze ograniczenie sprawdzające, aby to osiągnąć?</p><p>kontekstem tego jest próba ponownego wprowadzenia możliwości przechwytywania wyników nienumerycznych w istniejącym systemie. dodanie dwóch nowych kolumn do tabeli z ograniczeniem, aby zapobiec więcej niż jednemu wynikowi na wiersz, było najbardziej ekonomicznym podejściem, niekoniecznie poprawnym.</p><p>aktualizacja: przepraszamy, typ danych snafu. niestety nie zamierzałem interpretować typów wyników wskazanych jako typy danych sql server, tylko ogólne terminy, teraz naprawione.</p>
<p>następujące czynności powinny załatwić sprawę:</p><pre><code>create table mytable (col1 float null, col2 nvarchar(30) null, col3 datetime null); go alter table mytable add constraint checkonlyonecolumnisnull check ( ( case when col1 is null then 0 else 1 end + case when col2 is null then 0 else 1 end + case when col3 is null then 0 else 1 end ) = 1 ) go </code></pre>
Z ograniczeniem, że klauzula warunek może być „coś”, to jesteś ograniczony do skanowania całą listę i stosując warunek.


Jeśli istnieją ograniczenia dotyczące klauzuli stan, wtedy można spojrzeć na organizowanie danych do bardziej efektywnie obsługiwać zapytań.


Na przykład, przykładowy kod z „byFirstLetter” słowniku nie pomaga w ogóle z „endswith” zapytania.


Więc tak naprawdę sprowadza się do tego, co pyta chcesz zrobić przed tymi danymi.


W bazach danych, problem ten jest ciężar „optymalizator zapytań”. W typowej bazy danych, jeśli masz bazę danych bez indeksów, oczywiście każde zapytanie będzie skan tabeli. Jak dodać indeksów w tabeli, optymalizator może użyć tych danych do bardziej wyrafinowanych zapytań planuje lepiej dostać się do danych. To w istocie problem, który opisujesz.


Gdy masz bardziej konkretny podzbiór typów kwerend następnie można zrobić lepszą decyzję, co struktura jest najlepsza. Ponadto, należy wziąć pod uwagę ilość danych. Jeśli masz listę 10 elementów każdy mniej niż 100 bajtów, skan wszystko może okazać się najszybciej, co można zrobić, ponieważ masz taką małą ilość danych. Oczywiście, że nie skaluje się do elementów 1M, ale nawet sprytnych technik dostępu nosić koszt w instalacji, konserwacji (jak utrzymanie indeksu) i pamięć.


**EDIT** , na podstawie komentarza


Jeśli jest to auto Nieukończenie, jeśli dane są statyczne, a następnie posortować je i używać przeszukiwanie binarne. Nie jesteś naprawdę dzieje się szybciej niż to.


Jeśli dane są dynamiczne, a następnie zapisać go w zrównoważonym drzewie, i szukać tego. To skutecznie wyszukiwanie binarne, a to pozwala zachować dodać dane losowo.


Coś jeszcze jest jakaś specjalność na tych pojęć. ło panie. dobra. jeśli używasz entity framework, to wybierz wszystko, co jest w danej tabelce do zmiennej (i już masz dane 2 cache). sprawdzasz ile masz tam danych metodą count dostępną dla list. robisz tablicę dynamiczną i wrzucasz tam dane podzielone z listy. zwykły for od 0 do tego, ile zwróciło … druga pewnie jest dla sprawdzenia poprwanosci odpowiedzi, kucze nie pamietam dokladnie tych komend ale sprobuj skopjowac je z tej gotowej tabelki i ewentualnie cos pozmieniaj- a dokladniej t wspolrzedne pol zeby sie zgadzaly (wstaw tylko w pierwszych ramkach a reszte zlap za jeden rog i przeciagnij to ci sie skopiuje dla innych wynikow) Ok. Znalazłem to w czym problem.


Na początku myślałem, że to problem z DataProvided, ale to nie było. Odkryłem ten sam problem w SQLServer 2000 ....


Wyszukiwanie w google dowiedziałem się czegoś o plan wykonania. Biorąc w ten sposób, że zapytania zwiększyło wydajność 50%.


Krótki życiorys tego problemu jest to, że podczas wykonywania SP kodem, DBMS ma pewne problemy z planu wykonania, a nie korzystać z indeksów ...


Lepszą odpowiedź jest w tym poście:
 [Parametr Wąchania (lub Fałszowanie) w SQL Server](https://stackoverflow.com/questions/211355/parameter-sniffing-or-spoofing-in-sql-server)


Mam nadzieję, że to Ci pomoże. Jest to dość szerokie, ale dam ci tak ogólną odpowiedź, jak tylko mogę.

**CTE ...**

* Są niezindeksowalne (ale mogą używać istniejących indeksów na obiektach, do których istnieją odwołania)
* Nie można mieć ograniczeń
* Są zasadniczo jednorazowe `VIEW` s
* Trwać tylko do momentu uruchomienia następnego zapytania
* Może być rekurencyjny
* Nie masz dedykowanych statystyk (polegaj na statystykach dotyczących podstawowych obiektów)

**#Temp Tables ...**

* Są prawdziwe zmaterializowane tabele, które istnieją w tempdb
* Może być indeksowany
* Może mieć ograniczenia
* Trwaj w życiu obecnego POŁĄCZENIA
* Może odwoływać się do innych zapytań lub podprocedur
* Masz dedykowane statystyki generowane przez silnik

Jeśli chodzi o użycie każdego z nich, mają bardzo różne przypadki użycia.Jeśli masz bardzo duży zestaw wyników lub musisz odwołać się do niego więcej niż raz, umieść go w tabeli `#temp` .Jeśli ma być rekurencyjny, jednorazowy lub po prostu dla uproszczenia logicznego, preferowany jest `CTE` .

Ponadto należy `CTE`**nigdy nie używaj do wykonania**.Prawie nigdy nie przyspieszysz przy użyciu CTE, ponieważ znowu jest to widok jednorazowy.Możesz zrobić z nimi kilka fajnych rzeczy, ale przyspieszenie zapytania nie jest jednym z nich. Cóż, jeden z reaons dlaczego zajęcia zazwyczaj zawierają członków prywatnych z publicznymi pobierające / ustawiające jest dokładnie ponieważ mogą zweryfikować dane.


Jeśli masz numer niż może wynosić od 1 do 100, na pewno umieścić coś w seter, że sprawdza, a następnie może rzucić wyjątek, który jest złowionych przez kod. Powód jest prosty: jeśli nie rób tego w seter, trzeba pamiętać, że od 1 do 100 ograniczenie każdym razem, gdy go ustawić, co prowadzi do kodu duplikaty lub gdy go zapomnieć, prowadzi do nieprawidłowym stanie.


Jeśli chodzi o wydajność, jestem z Knuth tutaj:



> 
> „Powinniśmy zapomnieć o małej wydajności, powiedzmy około 97% czasu. Przedwczesna optymalizacja jest źródłem wszelkiego zła”
> 
> 
> To naprawdę zależy od rodzaju danych, które zabierasz powrotem. Ponieważ zbiór danych (w efekcie) tylko zbiór DataTable obiektów, można zwracać wiele różnych zestawów danych w jednym, a więc łatwiejsze, obiektu. 


Performance-mądry, jesteś bardziej prawdopodobne, aby uzyskać nieefektywność z zapytaniami niezoptymalizowanych niż z „niewłaściwym” wybór .NET konstruktu. Przynajmniej tak było moje doświadczenie. masz kilka możliwości: 

użyć pętli for i wewnątrz if

użyć pętli while

użyć po prostu filtra listy (\_\_ne\_\_ - not equal):

<https://www.online-python.com/uqefk1lvdj> 
pod względem wydajności najlepszy jest tutaj filtr. Na ten moment nie ma takiej możliwości. Aktualnie trwają testy, gdzie (przynajmniej niektórzy) użytkownicy iPhone'ów mają możliwość odnowienia serii za kasę (nie lingoty).


Licznik serii ma w założeniu pokazywać rzeczywistą serię dni nauki z rzędu. Danie zbyt dużych możliwości manipulowania nim trochę by wypaczyło jego sens. Otrzymywane lingoty (których widocznie ci nie brakuje) i liczba przy flagach to dodatki. 1 wyświetlenie z jednego ip.