Попробуйте следующее: -
SET @start_res = 20150301;
SET @finish_res= 20150501;
SET @finish_check= 20150801;
SET @start_check= 20150301;
SET @daily_hos= 3;
SELECT
(SELECT COUNT(DAY_IN) AS arr FROM t_hospital WHERE
DAY_IN between @start_check and @finish_check and
RES_DATE between @start_res and @finish_res and
ID_daily_hos =@daily_hos) e,
(SELECT COUNT(PAT_STATUS) AS ONG1 FROM t_hospital WHERE
PAT_STATUS like '%ong%' and
DAY_IN between @start_check and @finish_check and
RES_DATE between @start_res and @finish_res and
ID_daily_hos =@daily_hos) a,
(SELECT COUNT(PAT_STATUS) AS RTED FROM t_hospital WHERE
PAT_STATUS like '%rtde%' and
DAY_IN between @start_check and @finish_check and
RES_DATE between @start_res and @finish_res and
ID_daily_hos =@daily_hos)b,
(SELECT COUNT(PAT_STATUS) AS POLI FROM t_hospital WHERE
PAT_STATUS like '%pol%' and
DAY_IN between @start_check and @finish_check and
RES_DATE between @start_res and @finish_res and
ID_daily_hos =@daily_hos) c,
(SELECT COUNT(PAT_STATUS) AS para FROM t_hospital WHERE
PAT_STATUS like '%para%' and
DAY_IN between @start_check and @finish_check and
RES_DATE between @start_res and @finish_res and
ID_daily_hos =@daily_hos) d
В вашем вопросе упоминается о соединении двух таблиц, но, похоже, имеется только t_hospital
. Возможно, вы захотите обновить свой вопрос информацией о другой таблице.
если существует то же количество имен столбцов, поскольку существуют элементы в каждой строке, разве Вы не могли использовать для цикла?
var currentValues = currentRow.Split(separatorChar);
for(var i=0;i<columnList.Length;i++){
// use i to index both (or all) arrays and build your map
}
На функциональном языке Вы обычно находили бы функцию "zip", которая, надо надеяться, будет частью C#4.0. Bart Де-Смет обеспечивает забавную реализацию zip на основе существующих функций LINQ:
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(
this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> func)
{
return first.Select((x, i) => new { X = x, I = i })
.Join(second.Select((x, i) => new { X = x, I = i }),
o => o.I,
i => i.I,
(o, i) => func(o.X, i.X));
}
Затем можно сделать:
int[] s1 = new [] { 1, 2, 3 };
int[] s2 = new[] { 4, 5, 6 };
var result = s1.Zip(s2, (i1, i2) => new {Value1 = i1, Value2 = i2});
У Вас есть неочевидная псевдоошибка в Вашем первоначальном коде - IEnumerator<T>
, расширяется IDisposable
, таким образом, необходимо расположить его. Это может быть очень важно с блоками итератора! Не проблема для массивов, но был бы с другим IEnumerable<T>
реализации.
я сделал бы это как это:
public static IEnumerable<TResult> PairUp<TFirst,TSecond,TResult>
(this IEnumerable<TFirst> source, IEnumerable<TSecond> secondSequence,
Func<TFirst,TSecond,TResult> projection)
{
using (IEnumerator<TSecond> secondIter = secondSequence.GetEnumerator())
{
foreach (TFirst first in source)
{
if (!secondIter.MoveNext())
{
throw new ArgumentException
("First sequence longer than second");
}
yield return projection(first, secondIter.Current);
}
if (secondIter.MoveNext())
{
throw new ArgumentException
("Second sequence longer than first");
}
}
}
Затем можно снова использовать это каждый раз, когда у Вас есть потребность:
foreach (var pair in columnList.PairUp(currentRow.Split(separatorChar),
(column, value) => new { column, value })
{
// Do something
}
, Кроме того, Вы могли создать универсальный Парный тип и избавиться от параметра проекции в методе PairUp.
РЕДАКТИРОВАНИЕ:
С Парным типом, код вызова был бы похож на это:
foreach (var pair in columnList.PairUp(currentRow.Split(separatorChar))
{
// column = pair.First, value = pair.Second
}
, Который наводит справки столь простой, как можно добраться. Да, необходимо поместить служебный метод где-нибудь как повторно используемый код. Едва проблема, по моему мнению. Теперь для нескольких массивов...
, Если массивы имеют различные типы, у нас есть проблема. Вы не можете выразить произвольного числа параметров типа в общем методе / описание типа - Вы могли записать версии PairUp для стольких параметров типа, сколько Вы хотели, точно так же, как существует Action
и Func
делегаты максимум к 4 параметрам делегата - но Вы не можете сделать это произвольным.
, Если значения будут все иметь тот же тип, однако - и если Вы рады придерживаться массивов - это легко. (Немассивы хорошо также, но Вы не можете сделать длины, проверяющей заранее.) Вы могли сделать это:
public static IEnumerable<T[]> Zip<T>(params T[][] sources)
{
// (Insert error checking code here for null or empty sources parameter)
int length = sources[0].Length;
if (!sources.All(array => array.Length == length))
{
throw new ArgumentException("Arrays must all be of the same length");
}
for (int i=0; i < length; i++)
{
// Could do this bit with LINQ if you wanted
T[] result = new T[sources.Length];
for (int j=0; j < result.Length; j++)
{
result[j] = sources[j][i];
}
yield return result;
}
}
Затем код вызова был бы:
foreach (var array in Zip(columns, row, whatevers))
{
// column = array[0]
// value = array[1]
// whatever = array[2]
}
Это включает определенное количество копирования, конечно - Вы создаете массив каждый раз. Вы могли изменить это путем представления другого типа как это:
public struct Snapshot<T>
{
readonly T[][] sources;
readonly int index;
public Snapshot(T[][] sources, int index)
{
this.sources = sources;
this.index = index;
}
public T this[int element]
{
return sources[element][index];
}
}
Это, вероятно, рассматривалось бы как излишество большинством, хотя ;)
я мог продолжать придумывать все виды идей, быть честным..., но основы:
Используйте IEnumerator для обоих, был бы хороши
var currentValues = currentRow.Split(separatorChar);
using (IEnumerator<string> valueEnum = currentValues.GetEnumerator(), columnEnum = columnList.GetEnumerator()) {
while (valueEnum.MoveNext() && columnEnum.MoveNext())
valueMap.Add(columnEnum.Current, valueEnum.Current);
}
Или создал бы дополнительные методы
public static IEnumerable<TResult> Zip<T1, T2, TResult>(this IEnumerable<T1> source, IEnumerable<T2> other, Func<T1, T2, TResult> selector) {
using (IEnumerator<T1> sourceEnum = source.GetEnumerator()) {
using (IEnumerator<T2> otherEnum = other.GetEnumerator()) {
while (sourceEnum.MoveNext() && columnEnum.MoveNext())
yield return selector(sourceEnum.Current, otherEnum.Current);
}
}
}
Использование
var currentValues = currentRow.Split(separatorChar);
foreach (var valueColumnPair in currentValues.Zip(columnList, (a, b) => new { Value = a, Column = b }) {
valueMap.Add(valueColumnPair.Column, valueColumnPair.Value);
}
При реальном использовании массивов лучший способ состоит в том, чтобы, вероятно, только использовать стандартное for
цикл с индексами. Не как хорошая, предоставленный, но насколько я знаю.NET не предлагает лучший способ сделать это.
Вы могли также инкапсулировать свой код в метод, названный zip
†“, это - общая функция списка высшего порядка. Однако C#, испытывающий недостаток в подходящем Типе "кортеж", это является довольно неработоспособным. Вы закончили бы тем, что возвратились IEnumerable<KeyValuePair<T1, T2>>
, который не очень хорош.
Между прочим, Вы действительно используете IEnumerable
вместо IEnumerable<T>
или почему Вы бросаете эти Current
значение?
Вместо того, чтобы создать два отдельных массива Вы могли сделать двухмерную антенную решетку или словарь (который будет лучше). Но действительно, если это работает, я не попытался бы изменить его.